将 3D 数组与 2D 数组相乘

Multiply a 3D array with a 2D array

我有一个 3D numpy 数组,我想将它与一个 2D 数组相乘,3D 如下所示:

C= np.zeros((3, 2, 2))
C[0][0] = [0,0]
C[0][1] = [0,1]
C[1][0] = [1,0]
C[1][1] = [1,1]
C[2][0] = [1,2]
C[2][1] = [2,1]

二维数组如下所示:

V = np.zeros((3,2)) 
V[0][0] = 1
V[0][1] = 2
V[1][0] = 1
V[1][1] = 3
V[2][0] = 4 
V[2][1] = 5

结果R 是一个 2X2 二维数组(总共 4 个元素)R=[[5,8],[13,10]] 其中:

R[0] = V[0][0]*C[0][0]+V[1][0]*C[1][0]+V[2][0]*C[2][0] = [5,8] (first row of R)

R[1] = V[0][1]*C[0][1]+V[1][1]*C[1][1]+V[2][1]*C[2][1] = [13,10] (second row of R)

这只是一个示例,我如何通过 VC(没有 for 循环!)使用 numpy 矩阵乘法运算得到 R。请帮忙!

不好意思我后来做了一些编辑,评论是老例子,现在应该可以了

你的例子令人困惑。为什么你说你的预期结果是 [[1, 0], [5, 10]] 但在你的例子中你还说 R 应该是 [[5, 8], [13, 10]]?

我希望这只是您的错字,因为从您的示例中并不清楚您是如何从一个到另一个的。

无论如何:

(V.T * C.T).sum(axis=2).T

输出:

array([[ 5.,  8.],
       [13., 10.]])
In [20]: C          # (3,2,2)
Out[20]: 
array([[[0, 0],
        [0, 1]],

       [[1, 0],
        [1, 1]],

       [[1, 2],
        [2, 1]]])
In [21]: V         # (3,2)
Out[21]: 
array([[1., 2.],
       [1., 3.],
       [4., 5.]])

V 展开为 (3,2,1)。这个 broadcastsC 产生一个 (3,2,2):

In [22]: C * V[:,:,None]
Out[22]: 
array([[[ 0.,  0.],
        [ 0.,  2.]],

       [[ 1.,  0.],
        [ 3.,  3.]],

       [[ 4.,  8.],
        [10.,  5.]]])

并在第一个轴上求和得到 (2,2) 结果:

In [23]: (C * V[:,:,None]).sum(axis=0)
Out[23]: 
array([[ 5.,  8.],
       [13., 10.]])

这个答案清理了@ddjohns 的答案;他做了艰苦的工作。

sum-of-products可以用einsum表示为:

In [24]: np.einsum('ijk,ij->jk',C,V)
Out[24]: 
array([[ 5.,  8.],
       [13., 10.]])

重新排序轴,我们可以将其表示为更常规的sum-of-products:

In [25]: np.einsum('jki,ji->jk',C.transpose(1,2,0),V.transpose(1,0))
Out[25]: 
array([[ 5.,  8.],
       [13., 10.]])

并用它来将其转换为 matmul:

In [28]: (C.transpose(1,2,0)@V.transpose(1,0)[:,:,None]).squeeze(2)
Out[28]: 
array([[ 5.,  8.],
       [13., 10.]])

[28]可能是最快的,但是[23]可能更容易理解。