从没有循环的矩阵 B 的每一行中减去每一行矩阵 A



给定两个数组,A(形状:M X C)和B(形状:N X C),有没有办法在不使用循环的情况下从每行B中减去每一行A?最终输出将是形状(M N X C)。

<小时 />

示例

A = np.array([[  1,   2,   3], 
[100, 200, 300]])
B = np.array([[  10,   20,   30],
[1000, 2000, 3000],
[ -10,  -20,   -2]])

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

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

(循环太慢,"outer"减去每个元素而不是每一行)

通过利用以下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]])

或者,对于比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)

一种效率最低的方法是使用 np.repeat 和 np.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]])

使用 Kronecker 乘积 (numpy.kron):

>>> import numpy as np
>>> A = np.array([[  1,   2,   3], 
...               [100, 200, 300]])
>>> B = np.array([[  10,   20,   30],
...               [1000, 2000, 3000],
...               [ -10,  -20,   -2]])
>>> (m,c) = A.shape
>>> (n,c) = B.shape
>>> np.kron(A,np.ones((n,1))) - np.kron(np.ones((m,1)),B)
array([[   -9.,   -18.,   -27.],
[ -999., -1998., -2997.],
[   11.,    22.,     5.],
[   90.,   180.,   270.],
[ -900., -1800., -2700.],
[  110.,   220.,   302.]])

相关内容

  • 没有找到相关文章

最新更新