在 NumPy 中从列中减去行

Subtracting Row From Column in NumPy

我有一个 m 维 NumPy 数组 A 和一个 n 维 NumPy 数组 B
我想创建一个 m x n 矩阵 C 使得 C[i, j] = B[j] - A[i]
在 NumPy 中有 efficient/vectorized 的方法吗?

目前我正在使用:

C = np.zeros((M, N))
for i in range(0, M):
    C[i, :] = (B - A[i])

编辑:
m, n 是大数字,因此,C 是一个更大的矩阵(m*n 个条目)
我尝试了 np.repeatnp.subtract.outer 但它们都使我的 RAM 崩溃

我想你正在寻找 ǹp.subtract.outer

M = 5
N = 10

A = np.arange(N)
B = np.arange(M)
np.subtract.outer(A,B)

输出:

array([[ 0, -1, -2, -3, -4],
       [ 1,  0, -1, -2, -3],
       [ 2,  1,  0, -1, -2],
       [ 3,  2,  1,  0, -1],
       [ 4,  3,  2,  1,  0],
       [ 5,  4,  3,  2,  1],
       [ 6,  5,  4,  3,  2],
       [ 7,  6,  5,  4,  3],
       [ 8,  7,  6,  5,  4],
       [ 9,  8,  7,  6,  5]])

它将对 A 和 B 中的所有对应用减法。对于 1 维,它等同于

C = empty(len(A),len(B))
for i in range(len(A)):
    for j in range(len(B)):
        C[i,j] = A[i] - B[j]

编辑

如果您有内存问题,您可以尝试在执行操作之前分配输出缓冲区并适当设置 out 关键字:

C = np.zeros((M, N))
np.subtract.outer(B, A, out=C)

您可以在新轴上重复其中一个数组,然后减去另一个数组。

示例:

m = 10
n = 20

A = np.array(range(m))
B = np.array(range(n))
C = np.repeat(B[:, np.newaxis], m, axis=1) - A

那么 C 将包含:

array([[ 0, -1, -2, -3, -4, -5, -6, -7, -8, -9],
       [ 1,  0, -1, -2, -3, -4, -5, -6, -7, -8],
       [ 2,  1,  0, -1, -2, -3, -4, -5, -6, -7],
       [ 3,  2,  1,  0, -1, -2, -3, -4, -5, -6],
       [ 4,  3,  2,  1,  0, -1, -2, -3, -4, -5],
       [ 5,  4,  3,  2,  1,  0, -1, -2, -3, -4],
       [ 6,  5,  4,  3,  2,  1,  0, -1, -2, -3],
       [ 7,  6,  5,  4,  3,  2,  1,  0, -1, -2],
       [ 8,  7,  6,  5,  4,  3,  2,  1,  0, -1],
       [ 9,  8,  7,  6,  5,  4,  3,  2,  1,  0],
       [10,  9,  8,  7,  6,  5,  4,  3,  2,  1],
       [11, 10,  9,  8,  7,  6,  5,  4,  3,  2],
       [12, 11, 10,  9,  8,  7,  6,  5,  4,  3],
       [13, 12, 11, 10,  9,  8,  7,  6,  5,  4],
       [14, 13, 12, 11, 10,  9,  8,  7,  6,  5],
       [15, 14, 13, 12, 11, 10,  9,  8,  7,  6],
       [16, 15, 14, 13, 12, 11, 10,  9,  8,  7],
       [17, 16, 15, 14, 13, 12, 11, 10,  9,  8],
       [18, 17, 16, 15, 14, 13, 12, 11, 10,  9],
       [19, 18, 17, 16, 15, 14, 13, 12, 11, 10]])

这是一个简单的广播任务:

In [31]: A =np.arange(3); B=np.arange(4)
In [32]: C = B - A[:,None]
In [33]: C.shape
Out[33]: (3, 4)
In [34]: C
Out[34]: 
array([[ 0,  1,  2,  3],
       [-1,  0,  1,  2],
       [-2, -1,  0,  1]])

这类似于 的答案,但没有必要使用 repeat。这应该会稍微减少内存使用量,但如果 M*N*8 接近您的内存限制,则使用 C 的此操作或后续操作可能会达到该限制。