【问题标题】:Numpy multiply 3d matrix by 2d matrixNumpy 将 3d 矩阵乘以 2d 矩阵
【发布时间】:2025-11-29 07:15:01
【问题描述】:

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

[
[[1,1],[1,1]], 
[[2,2],[2,2]], 
[[3,3],[3,3]]
]

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

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

我想实现形状为 (3,2,2) 的 c,例如:

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

这给了

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

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

 [[6. 6.]
 [3. 3.]]]

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

谢谢。

【问题讨论】:

  • np.tensordot(A,B,axes=((2),(1))) 给出 [[[2 1] [2 1]] [[4 2], [4 2] ] [[6 3] [6 3]]],这与预期的不同。请问在我的情况下正确的方法应该是什么?
  • A 和 B 的典型形状是什么?各种方法的性能取决于它们。
  • A 的形状为 (n, 2, 2),其中 n 可以相当大。 B 的形状总是 (2, 2)。请问哪种方法比较好?

标签: python numpy


【解决方案1】:

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

np.tensordot(B,A,axes=((1),(1))).swapaxes(0,1)
np.tensordot(A,B,axes=((1),(1))).swapaxes(1,2)

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

时间安排 -

# Original approach
def orgapp(A,B):
    m = A.shape[0]
    n = B.shape[0]
    r = A.shape[2]
    c = np.zeros((m,n,r))
    for i in range(len(A)):
        c[i] = np.dot(B, A[i,:,:])
    return c  

In [91]: n = 10000
    ...: A = np.random.rand(n,2,2)
    ...: B = np.random.rand(2,2)

In [92]: %timeit orgapp(A,B)
100 loops, best of 3: 12.2 ms per loop

In [93]: %timeit np.tensordot(B,A,axes=((1),(1))).swapaxes(0,1)
1000 loops, best of 3: 191 µs per loop

In [94]: %timeit np.tensordot(A,B,axes=((1),(1))).swapaxes(1,2)
1000 loops, best of 3: 208 µs per loop

# @Bitwise's solution
In [95]: %timeit np.flip(np.dot(A,B).transpose((0,2,1)),1)
1000 loops, best of 3: 697 µs per loop

【讨论】:

  • @dxli 这篇文章解决了你的问题吗?如果是这样,请考虑接受它。
【解决方案2】:

另一种解决方案:

np.flip(np.dot(A,B).transpose((0,2,1)),1)

【讨论】:

    最近更新 更多