2015-05-04 26 views
6

yerine bir toplam matris döndürür. Ben numpy'li bir matris kullanarak oldukça karmaşık bir toplama yapıyorum. Matrisin şekli matrix.shape = (500, 500) şeklindedir ve dizinin şekli arr.shape = (25,) şeklindedir. , float64numpy.sum() öğesi, tek bir sayı yerine

np.sum() çok yavaş ve tek şamandıra döndürür:

İşte
totalsum = np.sum([i * matrix for i in arr]) 

anlamıyorum şudur: işleyişi aşağıdaki gibidir. Python'un sum.() ile aynı işlem, diğer bir deyişle

totalsum2 = sum([i*matrix for i in arr]) 

Amaçlı matrisin şekline korur. Yani, ortaya çıkan şekil totalsum2.shape() = (500, 500)'dur. Ha?

np.sum()'un özellikle numpy ndarrays ile çalışırken, sum()'dan daha uzun sürmesi garip olduğunu düşünüyorum.

Tam olarak burada neler oluyor? sum() ile karşılaştırıldığında yukarıdaki değerleri toplayan np.sum() nasıldır?

Matris şeklini korumak için np.sum() olmasını isterim. Boyutları, np.sum() matris boyutunu koruyacak ve tek bir float döndürmeyecek şekilde nasıl ayarlayabilirim?

+1

Bu işlem sadece np.sum (arr) * matrisi olarak yazılmalıdır. – Daniel

+0

@Ophion dizisi ve matris aynı şekilde değil. Tüm matrisi, dizideki her bir değerle çarpmak istiyorum. Sonra, ortaya çıkan tüm matrisleri toplamak istiyorum. – JesseTrevve

+0

Bu, einsum notasyonunda np.einsum ("k, ij-> ij", arr, matrix) 'olarak yazılabilir. Görülebileceği gibi tensörler arasında ortak bir endeks yoktur. Yukarıdaki yöntemlerden herhangi birini ve doğru olarak seçtiğiniz yanıtı hesaplayarak bunu kendiniz doğrulayabilirsiniz. – Daniel

cevap

5

Sen np aramalıdır:

Bu

kullanılarak yapılabilir.

totalsum = np.sum([i * matrix for i in arr], 0) 

Alternatif (yani sizin liste anlama tarafından oluşturulan tek eksen 0 üzerinde toplam,) 0 olarak ayarlanmış opsiyonel eksen parametresi Özetle, bir jeneratör değerlendirmek np.sum yüzden parantez atlayabilirsiniz.

totalsum = np.sum(i * matrix for i in arr) 
+1

Eksen parametresi = 0'a izin vermek, eksen üzerinde "toplanma yok" yerine "eksen 0’nın üzerinde toplama yapmaktır". Bu, çalışılan liste anlaşmanın etkili bir şekilde 3 boyutlu bir veri yapısı yaratması, çünkü Numpy tarafından alınan ilk (0) eksenin çarpılan "matris" in tüm kopyalarının "istiflenmesi" ile yaratılan boyut olduğunu gösterir. – jsbueno

2
[i*matrix for i in arr] # list of matrices 

Yukarıdaki liste, toplamları kullandığınızda dizileri ekleyeceğiniz bir matris listesidir.

In [6]: matrix = np.array([[1,2],[3,4]]) 

In [7]: matrix 
Out[7]: 
array([[1, 2], 
     [3, 4]]) 


In [9]: [i * matrix for i in (2,4,8)] 
Out[9]: 
[array([[2, 4], 
     [6, 8]]), array([[ 4, 8], 
     [12, 16]]), array([[ 8, 16], 
     [24, 32]])] 

Size bir ekseni tanımlamak yoksa tüm boyutları üzerinde özetleyecek söylüyor np.sum

File:  /home/ale/.virtualenvs/ml/local/lib/python2.7/site-packages/numpy/core/fromnumeric.pyaxis=None, dtype=None, out=None, keepdims=False) Docstring: Sum of array elements over a given axis. 

Parameters 
---------- a : array_like 
    Elements to sum. axis : None or int or tuple of ints, optional 
    Axis or axes along which a sum is performed. 
    The default (`axis` = `None`) is perform a sum over all 
    the dimensions of the input array. `axis` may be negative, in 
    which case it counts from the last to the first axis. 

    .. versionadded:: 1.7.0 

için lütfen yardıma bakın. Örnek: np.sum neden daha uzun sürüyor? iyi sezgi, [i*matrix for i in arr] ifadesinde, her bir i için yeni bir dizi oluşturduğunuzu söyler, bu durumda np.sum tüm dizileri toplar.

Başka sebep de olabilir, ama sanırım öyle.

+0

Matris/matrisleri düzeltmeye çalıştım, ancak düzenlemeleri de yaptınız, bu yüzden umarım artık cevabı en son düzenlemenize döndürdüm. – Paul

+0

Düzenleme için teşekkürler @Paul. – Ale

+1

@Ale Numpy, ilk önce tüm i i matris dizilerini oluşturacaktır. Ardından np.sum, diziler listesinden bir 3B dizi oluşturulduğunda. Ek yük tüm ekstra bellek içi kopyalama. – Daniel

4

Python'un sıralı sum() görevi o listedeki her öğeyi alıyor ve bunları bir araya getiriyor. Aynı boyuttaki diziler birlikte eklendiğinde, bunları yalnızca element olarak eklersiniz. np.sum ile, bir eksen veya eksen boyunca ekliyoruz Oysa

test1 = np.array([[4,3],[2,1]]) 
test2 = np.array([[8,9],[1,1]]) 
print test1 + test2 

İade

[[12,12] 
[3,2]] 

: Örneğin. Bir dizide olan şeyleri korumak istiyorsanız ve np.sum kullanmak istiyorsanız, işleminizi (i ile diziyle çarpın) üçüncü bir boyuta yansıtmak ve np.sum (axis = 2) kullanmak isteyeceksiniz. .

np.sum(matrix[:,:,np.newaxis] * array[np.newaxis,np.newaxis,:],axis=2) 
+0

Sadece O.P.'nin çağrısında "axis = 0" ileterek çalışır: Onun anlaşılması, birinci eksenin istenen olan üç boyutlu bir veri yapısı oluşturur. – jsbueno

+0

Tom: @jsbueno doğrudur. "Axis = 0" kelimesinin geçilmesi totalsum.shape = (500, 500) değerini verir. "Axis = 2" kelimesinin geçilmesi totalsum.shape = (24, 500) değerini verir. – JesseTrevve

+0

Evet, eksen = 0, Yoann yöntemiyle bir şeyler yaparsanız kullanmak istediğiniz şeydir. Ve yaptığım birkaç hızlı teste dayanarak, hesaplama süresi sınırlı iseniz kullanmak istediğiniz yöntem budur. Ancak, gösterdiğim örnek için, eksen = 2'yi kullanmanız gerekir. Alternatif olarak, np.newaxis konumlarını, toplamak istediğiniz ekseni = 0 yapmak için yeniden düzenleyebilirsiniz. – Tom

İlgili konular