【发布时间】:2019-11-19 00:53:57
【问题描述】:
为了讨论,我有一个形状为 2x2 的 2D 矩阵 (A) 和一个形状为 2x2x10 的 3D 矩阵 (B)。我目前正在遍历矩阵 B 的最后一个轴,并一次构造一个完整的矩阵一个子矩阵。
A = np.random.random((2,2))
B = np.random.random((2,2,10))
C = np.zeros_like(B)
for i in range(B.shape[-1]):
C[:,:,i] = A @ B[:, :, i]
实际上,我的矩阵比这大得多,我知道肯定有比 for 循环更有效的东西。我已经查看了几个先前的问题,其中解决方案涉及使用 np.tensordot 或 np.einsum,但坦率地说,我认为我没有正确使用它。
# Basic
C_basic = A @ B
print(f'Basic {np.allclose(C, C_basic)}') # False
# Einsum
C_einsum = np.einsum('ij, jik-> ijk', A, B)
print(f'np.einsum {np.allclose(C, C_einsum)}') # False
# Newaxis
C_newaxis = A[np.newaxis, ...] @ B
print(f'np.newaxis {np.allclose(C, C_newaxis)}') # False
# Swapaxes
C_swapaxes = A @ np.swapaxes(B, 0, 2)
C_swapaxes = np.swapaxes(C_swapaxes, 0, 2)
print(f'np.swapaxes {np.allclose(C, C_swapaxes)}') # False
【问题讨论】:
-
如果你的
B是 (10,2,2),那么A@B应该可以工作,结果是 (10,2,2)。如果A是 (2,3) 和B是 (3,4,10) 可能更容易测试。也就是说,使相加的轴与众不同(此处为 3)。在您的最后一种情况下,您需要另一个swapaxes。在einsum -
einsum表达式应该是 'ij,jkl->ikl' - 点和在j上,其余点在i和k和l作为批次(这是为了搭便车)。@与 'i,j,k' 一起使用。批次维度必须是第一位的。
标签: python numpy matrix-multiplication