2015-05-04 117 views
6

我正在使用numpy矩陣進行相當複雜的求和。 矩陣的形狀爲matrix.shape = (500, 500),陣列的形狀爲arr.shape = (25,)。操作如下:Make numpy.sum()返回矩陣的總和而不是單個數字

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

這是我不明白:

np.sum()很慢,並返回一個浮點,float64。這樣做與Python的sum.()相同的操作,即

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

保留矩陣的形狀。也就是說,生成的形狀是totalsum2.shape() = (500, 500)。咦?

我也覺得奇怪的是np.sum()需要比sum()更長的時間,特別是當我們使用numpy ndarrays時。

這裏究竟發生了什麼? np.sum()sum()相比,如何計算上述值?

我想np.sum()保存矩陣形狀。我如何設置尺寸以便np.sum()保留矩陣大小並且不返回單個浮點數?

+1

這個操作應該簡單寫成'np.sum(arr)* matrix'。 – Daniel

+0

@Ophion陣列和矩陣的形狀不一樣。我想將整個矩陣乘以數組中的每個值。然後,我想總結所有得到的矩陣。 – JesseTrevve

+0

這可以用'np.einsum(「k,ij-> ij」,arr,matrix)''作爲''''作爲'可以看出張量之間沒有共同的指標。您可以通過計算上述任何方法和您選擇的正確答案來自行驗證。 – Daniel

回答

5

必須調用NP:

這是可以做到用。使用可選的軸參數設置爲0(在0軸總和,即通過列表理解創建的)

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

或者綜上所述,你可以省略括號所以np.sum評估發電機。

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

讓軸參數= 0,而不是在軸上「不求和」,而是「取決於軸0」。它的工作原理是因爲所使用的列表理解有效地創建了一個3維數據結構,Numpy採用的第一個(第0)軸是通過「堆積」乘法矩陣的所有副本而創建的維度。 – jsbueno

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

以上列表是矩陣列表,因此當您使用sum時,它將添加數組。

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]])] 

請查看幫助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 

它說,如果不限定軸線,將總和所有尺寸。例如:

In [4]: np.sum(np.array([[1,2],[3,4]])) # 1 + 2 + 3 + 4... 
Out[4]: 10 

爲什麼np.sum需要更長的時間?好直覺說,在表達式[i*matrix for i in arr]中,你正在爲每個i創建一個新的數組,然後np.sum將總和所有數組。

可能還有其他原因,但我猜是這樣。

+0

我試圖修復矩陣/矩陣,但是您也進行了編輯,所以我希望現在可以將答案設置回您的上次編輯。 – Paul

+0

感謝@Paul的編輯。 – Ale

+1

@Ale Numpy將首先構建所有'i *矩陣'數組,然後在調用'np.sum'時,從數組列表中構建3D數組。開銷是所有額外的內存中複製。 – Daniel

4

Python的常規sum()任務正在將該列表中的每個項目添加到一起。當相同大小的數組一起添加時,您只需將它們添加到元素中。例如:

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

返回

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

而用np.sum,你是沿着一個軸或軸加入。如果你想維護數組中的東西,並且你想使用np.sum,你需要將你的操作(在數組中乘以i)投影到第三維,然後使用np.sum(axis = 2) 。

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

它只是通過在O.P.的調用中傳遞「axis = 0」來工作:他的理解創建了一個三維數據結構,其中第一個軸是所需的一個。 – jsbueno

+0

Tom:@jsbueno是正確的。傳遞「axis = 0」給出totalsum.shape =(500,500)。傳遞「axis = 2」給出totalsum.shape =(24,500)。 – JesseTrevve

+0

是的,如果你通過Yoann的方法做事情,axis = 0就是你想要使用的。而且,基於我做的一些快速測試,如果計算時間有限,那就是您想要使用的方法。但對於我展示的例子,您需要使用axis = 2。或者,您可以重新排列np.newaxis位置以使axis = 0成爲您想要求和的那個位置。 – Tom