仅使用广播从指定列向量处的矩阵中减去列向量

Subtract a column vector from matrix at specified vector of columns using only broadcast

我想使用另一个向量从 numpy 矩阵中减去一个列向量,该向量是需要从主矩阵中减去第一个列向量的列的索引。例如

M = array([[  1,   2,   1,   1],
           [  2,   1,   1,   1],
           [  1,   1,   2,   1],
           [  2,   1,   1,   1],
           [  1,   1,   1,   2]])  # An example matrix

V = array([1, 1, 1, 1, 1]) # An example column vector

I = array([0, 3, 2, 3, 1, 3, 3]) # The index maxtrix

现在我想在 I 中给出的列号处从 M 中减去 V。 例如。 I[0] 为 0,因此从矩阵 M.

的第一列(零索引)减去 V

同理I[1] = 3,从矩阵M的第四列(三个索引)减去V

运算结束时,由于3在I中出现了4次,所以V会在第三列即最后一列M减4次

我需要只使用广播而不是循环来完成此操作。

我试过以下方法:

M[:, I] - V[np.newaxis, :].T

但最终广播的结果矩阵比 M 中的列更多。

我们可以在 M -

的转置视图上使用 np.subtract.at
np.subtract.at(M.T,I,V)

可以使用 bincountouter

>>> M - np.outer(V, np.bincount(I, None, M.shape[1]))
array([[ 0,  1,  0, -3],
       [ 1,  0,  0, -3],
       [ 0,  0,  1, -3],
       [ 1,  0,  0, -3],
       [ 0,  0,  0, -2]])

subtract.at

>>> out = M.copy()
>>> np.subtract.at(out, (np.s_[:], I), V[:, None])
>>> out
array([[ 0,  1,  0, -3],
       [ 1,  0,  0, -3],
       [ 0,  0,  1, -3],
       [ 1,  0,  0, -3],
       [ 0,  0,  0, -2]])