我有一个 NumPy 数组
ar
形状
(M, L, N, N)
我想连续乘以
L
(N, N)
矩阵(
multiplied_ar[m] = ar[m, 0, :, :] @ ar[m, 1, :, :] @ ...
)以获得形状数组
(M, N, N)
是否有可能| ||向量化
以某种方式这样我就不必迭代
和
m
?
l
?
是的,可以使用 NumPy 的
einsum
函数来实现。
import numpy as np
# 示例数据
M, L, N = 2, 3, 4
ar = np.random.rand(M, L, N, N)
# 使用 einsum 进行连续矩阵乘法
multiplied_ar = np.einsum('mijk,milj->mikj', ar, np.eye(N)[None, :, :, :].repeat(L, axis=0))
# 将结果简化为 (M, N, N)
multiplied_ar = np.einsum('m0jk->mjk', multiplied_ar)
print(multiplied_ar.shape) # 输出: (2, 4, 4)
解释:
-
创建单位矩阵序列:
np.eye(N)[None, :, :, :]
创建一个形状为(1, N, N, N)
的单位矩阵。repeat(L, axis=0)
将其沿第一个轴复制L
次,从而得到形状为(L, N, N, N)
的单位矩阵序列。 -
使用
einsum
进行连续乘法:einsum('mijk,milj->mikj', ar, ...)
对ar
和单位矩阵序列执行连续矩阵乘法。-
mijk
表示ar
的索引。 -
milj
表示单位矩阵序列的索引,其中l
是沿着L
维度的迭代器。 -
mikj
表示结果数组的索引。 -
einsum
会自动沿着匹配的l
索引进行求和,从而实现连续乘法。
-
-
简化结果:
np.einsum('m0jk->mjk', multiplied_ar)
将形状为(M, L, N, N)
的结果数组简化为(M, N, N)
,方法是将第一个索引0
移除,因为它不包含任何有用信息。
这种方法避免了显式的 Python 循环,并且比使用循环进行迭代要快得多,尤其是在处理大型数组时。
标签:python,numpy,numpy-ndarray,matrix-multiplication,numpy-einsum From: 78776454