NumPy数组每列负数元素之和

3

您知道如何在NumPy数组的每列中汇总所有负元素吗?例如:

>>> d
array([[ 1,  2,  3],
       [-1, -1,  9],
       [ 7, -6,  4]])

我需要获取 [-1,-7,0]。是否有相应的函数可以实现此功能?

1个回答

13

以下列出几种可能的方法:

((d<0)*d).sum(0)
np.where(d<0,d,0).sum(0)
np.einsum('ij,ij->j',d<0,d)
((d - np.abs(d)).sum(0))/2

所有方法的示例逐步运行说明:

1)输入数组:

In [3]: d
Out[3]: 
array([[ 1,  2,  3],
       [-1, -1,  9],
       [ 7, -6,  4]])

2) 负数元素的掩码:

In [4]: d<0
Out[4]: 
array([[False, False, False],
       [ True,  True, False],
       [False,  True, False]], dtype=bool)

3) 使用逐元素乘法从输入数组中获取掩码的负元素 :

In [5]: (d<0)*d
Out[5]: 
array([[ 0,  0,  0],
       [-1, -1,  0],
       [ 0, -6,  0]])

4) 最后,沿着axis=0求和以对每列进行求和:

In [6]: ((d<0)*d).sum(axis=0) # Or simply ((d<0)*d).sum(0)
Out[6]: array([-1, -7,  0])

方法#2:3)使用np.where交替获取步骤(3)的结果:

In [7]: np.where(d<0,d,0)
Out[7]: 
array([[ 0,  0,  0],
       [-1, -1,  0],
       [ 0, -6,  0]])

第三种方法:3,4)使用np.einsum一步完成掩码和数组的逐元素乘法,并得到总和。

In [8]: np.einsum('ij,ij->j',d<0,d)
Out[8]: array([-1, -7,  0])

方法#4:获取输入数组的绝对值并从数组本身中减去,从而使我们得到负元素的两倍,正值被取消:

In [9]: d - np.abs(d)
Out[9]: 
array([[  0,   0,   0],
       [ -2,  -2,   0],
       [  0, -12,   0]])

沿每列求和并除以2以获得所需的输出:

In [10]: (d - np.abs(d)).sum(0)
Out[10]: array([ -2, -14,   0])

In [11]: ((d - np.abs(d)).sum(0))/2
Out[11]: array([-1, -7,  0])

1
最后一种方法有两个缺点:它可能会导致溢出,而其他方法仍然可以工作,并且它会在Python3中返回一个浮点数组。也许更好的方法是 ((d - np.abs(d)) // 2).sum(0)(虽然这并不能解决所有溢出问题,但至少可以解决一些)。 - MSeifert
非常感谢!我只想确认一下对于第一个选项而言:((d<0)*d).sum(0) 中括号内的零是指轴(列),第二个 d 是因为在括号内我们得到了一个真/假矩阵(例如零和一)。因此,在此之后,为了获得总和,我们必须乘以 d? - noami shal
@noamishal,如果有帮助的话,请查看刚刚添加的逐步运行说明。 - Divakar
@noamishal,已发布的解决方案和评论是否解决了您的疑问? - Divakar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接