我有一个形状矩阵Y(n,d)。我已经按以下方式计算了成对行差异:
for i in range(Y.shape[0]):
for j in range(Y.shape[0]):
C[i,:] = C[i,:] + W[i, j] * (Y[i, :]-Y[j, :])
不,我想创建一个3d数组,包含位置(i,j,:)的Y行和j的差异。你会怎么做?
它的目的是取代这个效率低下的循环:
<welcome-file-list>
<welcome-file>login.html</welcome-file>
</welcome-file-list>
答案 0 :(得分:1)
我已经找到了一些成功:
row_diffs = Y[:, np.newaxis] - Y
Y[:, np.newaxis]
创建尺寸为(n,1,3)的Y版本。然后,减法使用broadcasting来做你想要的。
不幸的是,我发现这种方法相对较慢,我还没有找到更好的方法。
完整示例:
>>> x = np.random.randint(10, size=(4, 3))
>>> x
array([[4, 0, 8],
[8, 5, 3],
[4, 1, 6],
[2, 2, 4]])
>>> x[:, np.newaxis] - x
array([[[ 0, 0, 0],
[-4, -5, 5],
[ 0, -1, 2],
[ 2, -2, 4]],
[[ 4, 5, -5],
[ 0, 0, 0],
[ 4, 4, -3],
[ 6, 3, -1]],
[[ 0, 1, -2],
[-4, -4, 3],
[ 0, 0, 0],
[ 2, -1, 2]],
[[-2, 2, -4],
[-6, -3, 1],
[-2, 1, -2],
[ 0, 0, 0]]])
答案 1 :(得分:0)
这是使用broadcasting
和np.einsum
的矢量化方法 -
np.einsum('ij,ijk->ik',W,Y[:,None] - Y)
运行时测试 -
In [29]: def original_app(Y,W):
...: m = Y.shape[0]
...: C = np.zeros((m,m))
...: for i in range(Y.shape[0]):
...: for j in range(Y.shape[0]):
...: C[i,:] = C[i,:] + W[i, j] * (Y[i, :]-Y[j, :])
...: return C
...:
In [30]: # Inputs
...: Y = np.random.rand(100,100)
...: W = np.random.rand(100,100)
...:
In [31]: out = original_app(Y,W)
In [32]: np.allclose(out, np.einsum('ij,ijk->ik',W,Y[:,None] - Y))
Out[32]: True
In [33]: %timeit original_app(Y,W)
10 loops, best of 3: 70.8 ms per loop
In [34]: %timeit np.einsum('ij,ijk->ik',W,Y[:,None] - Y)
100 loops, best of 3: 4.01 ms per loop