每行向量化一个二维数组和另一个二维数组之间的 NumPY 点积

Vectorize NumPY Dot Product Between a 2D array and Another 2D Array per Row

你好堆栈溢出,

我可以通过循环获得所需的结果,但想知道如何在二维数组的每行中应用点积。我正在尝试从 A 中取出每一行,并用 B 应用一系列点积。现在我的中间结果有点不稳定,但我确实得到了我想要的结果。希望矢量化并消除循环。

A = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
B = np.array([[9,-1,8],[-12,20,-5],[6,1,4]])
int_result = np.ones((len(A),3))
for r in np.arange(0,len(A)):
    int_result[r] = A[r].T.dot(B).dot(A[r])
print(int_result)
desired_result = int_result[:,0]
print(desired_result)

中间结果

[[ 117.  117.  117.]  
[ 744.  744.  744.]  
[1911. 1911. 1911.]  
[3618. 3618. 3618.]]

期望的结果

[ 117.  744. 1911. 3618.]

这是 2 np.matmul 次乘法,使用 A 的第一个维度作为 batch 维度:

In [55]: A = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
    ...: B = np.array([[9,-1,8],[-12,20,-5],[6,1,4]])
In [56]: A
Out[56]: 
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12]])
In [57]: B
Out[57]: 
array([[  9,  -1,   8],
       [-12,  20,  -5],
       [  6,   1,   4]])
In [58]: A.shape
Out[58]: (4, 3)
In [59]: B.shape
Out[59]: (3, 3)

将维度添加到A使其成为(4,1,3)和(4,3,1),我们可以这样做:

In [60]: (A[:,None,:]@B@A[:,:,None]).shape
Out[60]: (4, 1, 1)

并删除大小为 1 的维度:

In [61]: (A[:,None,:]@B@A[:,:,None]).squeeze()
Out[61]: array([ 117,  744, 1911, 3618])

einsum 等价物同样好:

In [62]: np.einsum('ij,kj,ik->i',A,B,A)
Out[62]: array([ 117,  744, 1911, 3618])

在你的循环中:

In [65]: r=3; A[r]@B@A[r]    # A[r] is 1d, so T isn't needed
Out[65]: 3618