从矩阵B的每一行中减去矩阵A的每一行而无循环

coo*_*ist 4 python numpy matrix linear-algebra numpy-broadcasting

给定两个数组A(shape:MXC)和B(shape:NXC),有没有一种方法可以AB不使用循环的情况下从每一行中减去每一行?最终输出将是形状(MNXC)。


A = np.array([[  1,   2,   3], 
              [100, 200, 300]])

B = np.array([[  10,   20,   30],
              [1000, 2000, 3000],
              [ -10,  -20,   -2]])
Run Code Online (Sandbox Code Playgroud)

所需结果(可以具有其他形状)(已编辑):

array([[  -9,   -18,   -27],
       [-999, -1998, -2997],
       [  11,    22,     5],
       [  90,   180,   270],
       [-900, -1800, -2700],
       [ 110,   220,   302]])

Shape: 6 X 3
Run Code Online (Sandbox Code Playgroud)

(循环太慢,“外部”减去每个元素而不是每一行)

kma*_*o23 5

可以通过以下方式有效地做到这一点(不使用任何循环)broadcasting

In [28]: (A[:, np.newaxis] - B).reshape(-1, A.shape[1])
Out[28]: 
array([[   -9,   -18,   -27],
       [ -999, -1998, -2997],
       [   11,    22,     5],
       [   90,   180,   270],
       [ -900, -1800, -2700],
       [  110,   220,   302]])
Run Code Online (Sandbox Code Playgroud)

或者,对于比更快的解决方案broadcasting,我们将不得不使用numexpr,例如:

In [31]: A_3D = A[:, np.newaxis]
In [32]: import numexpr as ne

# pass the expression for subtraction as a string to `evaluate` function
In [33]: ne.evaluate('A_3D - B').reshape(-1, A.shape[1])
Out[33]: 
array([[   -9,   -18,   -27],
       [ -999, -1998, -2997],
       [   11,    22,     5],
       [   90,   180,   270],
       [ -900, -1800, -2700],
       [  110,   220,   302]], dtype=int64)
Run Code Online (Sandbox Code Playgroud)

一种效率最低的方法是使用np.repeatnp.tile来匹配两个数组的形状。但是,请注意,这样做效率最低,因为在尝试匹配形状时会进行复制

In [27]: np.repeat(A, B.shape[0], 0) - np.tile(B, (A.shape[0], 1))
Out[27]: 
array([[   -9,   -18,   -27],
       [ -999, -1998, -2997],
       [   11,    22,     5],
       [   90,   180,   270],
       [ -900, -1800, -2700],
       [  110,   220,   302]])
Run Code Online (Sandbox Code Playgroud)