Numpy 将 3d 矩阵乘以 2d 矩阵

dxl*_*xli 6 python numpy

例如,我得到了形状为 (3,2,2) 的矩阵 A,例如

[
[[1,1],[1,1]], 
[[2,2],[2,2]], 
[[3,3],[3,3]]
]
Run Code Online (Sandbox Code Playgroud)

和形状(2,2)的矩阵B,例如

[[1, 1], [0,1]]
Run Code Online (Sandbox Code Playgroud)

我想实现 c 的形状 (3,2,2) 像:

c = np.zeros((3,2,2))
for i in range(len(A)):
    c[i] = np.dot(B, A[i,:,:])
Run Code Online (Sandbox Code Playgroud)

这使

[[[2. 2.]
  [1. 1.]]

 [[4. 4.]
 [2. 2.]]

 [[6. 6.]
 [3. 3.]]]
Run Code Online (Sandbox Code Playgroud)

实现这一目标的最有效方法是什么?

谢谢。

Div*_*kar 3

使用np.tensordot然后交换轴。所以,使用其中之一 -

\n\n
np.tensordot(B,A,axes=((1),(1))).swapaxes(0,1)\nnp.tensordot(A,B,axes=((1),(1))).swapaxes(1,2)\n
Run Code Online (Sandbox Code Playgroud)\n\n

我们可以A在交换轴后重塑为 2D,使用 2D 矩阵乘法以及np.dot重塑和交换轴来获得边际性能提升。

\n\n

时间安排 -

\n\n
# Original approach\ndef orgapp(A,B):\n    m = A.shape[0]\n    n = B.shape[0]\n    r = A.shape[2]\n    c = np.zeros((m,n,r))\n    for i in range(len(A)):\n        c[i] = np.dot(B, A[i,:,:])\n    return c  \n\nIn [91]: n = 10000\n    ...: A = np.random.rand(n,2,2)\n    ...: B = np.random.rand(2,2)\n\nIn [92]: %timeit orgapp(A,B)\n100 loops, best of 3: 12.2 ms per loop\n\nIn [93]: %timeit np.tensordot(B,A,axes=((1),(1))).swapaxes(0,1)\n1000 loops, best of 3: 191 \xc2\xb5s per loop\n\nIn [94]: %timeit np.tensordot(A,B,axes=((1),(1))).swapaxes(1,2)\n1000 loops, best of 3: 208 \xc2\xb5s per loop\n\n# @Bitwise\'s solution\nIn [95]: %timeit np.flip(np.dot(A,B).transpose((0,2,1)),1)\n1000 loops, best of 3: 697 \xc2\xb5s per loop\n
Run Code Online (Sandbox Code Playgroud)\n