Python 对矩阵行求和,不包括来自其他数组的索引

Python 对矩阵行求和,不包括来自其他数组的索引,python,numpy,Python,Numpy,假设我有一些矩阵,W=MxN和一个长的指数数组z,形状为Mx1 现在,假设我想对W中每一行的元素求和,不包括z中该行的索引 一维示例: import numpy as np W = np.array([1.0, 2.0, 8.0]) z = 2 np.sum(np.delete(W,z)) MxN示例和所需的输出: import numpy as np W = np.array([[1.0,2.0,8.0], [5.0,15.0,3.0]]) z = np.array([0,2]).res

假设我有一些矩阵,W=MxN和一个长的指数数组z,形状为Mx1

现在,假设我想对W中每一行的元素求和,不包括z中该行的索引

一维示例:

import numpy as np

W = np.array([1.0, 2.0, 8.0])
z = 2
np.sum(np.delete(W,z))
MxN示例和所需的输出:

import numpy as np

W = np.array([[1.0,2.0,8.0], [5.0,15.0,3.0]])
z = np.array([0,2]).reshape(2,1)

# desired output
# [10. 20.]
我尝试使用
np.delete
axis=1
,但没有成功

我设法通过以下技巧绕过它:

W = np.array([[1.0,2.0,8.0], [5.0,15.0,3.0]])
z = np.array([0,2])
W[np.arange(z.shape[0]), z]=0
print(np.sum(W, axis=1))
# [10. 20.]
但是我想知道是否有更优雅的方法。

使用来让掩码模拟
删除,然后求和减少-

(W*(z != np.arange(W.shape[-1]))).sum(-1)
样本运行-

对于2D情况:

In [61]: W = np.array([[1.0,2.0,8.0], [5.0,15.0,3.0]])
    ...: z = np.array([0,2]).reshape(2,1)

In [62]: (W*(z != np.arange(W.shape[-1]))).sum(-1)
Out[62]: array([10., 20.])
同样适用于1D情况:

In [59]: W = np.array([1.0, 2.0, 8.0])
    ...: z = 2

In [60]: (W*(z != np.arange(W.shape[-1]))).sum(-1)
Out[60]: 3.0

对于2D情况:

In [61]: W = np.array([[1.0,2.0,8.0], [5.0,15.0,3.0]])
    ...: z = np.array([0,2]).reshape(2,1)

In [62]: (W*(z != np.arange(W.shape[-1]))).sum(-1)
Out[62]: array([10., 20.])
对于
总和缩减
-

In [53]: np.einsum('ij,ij->i',W,z != np.arange(W.shape[1]))
Out[53]: array([10., 20.])

求和然后减去
2D
案例的z索引值-

In [134]: W.sum(1) - np.take_along_axis(W,z,axis=1).squeeze(1)
Out[134]: array([10., 20.])
扩展以处理二维和一维情况-

W.sum(-1)-np.take_along_axis(W,np.atleast_1d(z),axis=-1).squeeze(-1)

@迪瓦卡的答案很好。我只是从另一个角度来看待你的问题。如果需要屏蔽来忽略某些索引并对数组执行多个操作,则应使用numpy屏蔽数组
np.ma.array
,而不是常规的
np.array
。屏蔽数组的真正目的是忽略某些索引

从这个
W_ma
屏蔽数组中,您可以执行几乎所有与
np.array
相同的操作。对于
sum

W_ma.sum(1)

Out[44]:
masked_array(data=[10.0, 20.0],
             mask=[False, False],
       fill_value=1e+20)
要将遮罩数组转换为常规数组,可以使用
压缩
填充
、或
压缩行数

In [46]: W_ma.sum(1).compressed()
Out[46]: array([10., 20.])

注意:我强调,当您对忽略索引执行多个操作时,掩码数组非常有用。若您只需要对忽略索引执行一个或两个操作,那个么使用屏蔽数组是并没有意义的