2015-05-04 118 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