Python 多维矩阵(/数组)的矩阵乘法-如何避免循环?

Python 多维矩阵(/数组)的矩阵乘法-如何避免循环?,python,arrays,numpy,matrix,multidimensional-array,Python,Arrays,Numpy,Matrix,Multidimensional Array,我试图用包含多个要相乘的矩阵的数组来计算矩阵乘法。使用np.dot(或Py3.5+中的新@操作符)使用两个矩阵可以很容易地实现这一点,但我正在努力扩展它以有效地评估多维数组 例如,假设矩阵A的形状为(5,3,3),矩阵B的形状为(5,3)。现在,我想为每5个案例的后面部分建立多个矩阵:即do res[0] = np.dot(A[0], B[0]) res[1] = np.dot(A[1], B[1]) etc 我可以使用循环成功地实现这一点,例如: A = np.random.random((

我试图用包含多个要相乘的矩阵的数组来计算矩阵乘法。使用np.dot(或Py3.5+中的新@操作符)使用两个矩阵可以很容易地实现这一点,但我正在努力扩展它以有效地评估多维数组

例如,假设矩阵A的形状为(5,3,3),矩阵B的形状为(5,3)。现在,我想为每5个案例的后面部分建立多个矩阵:即do

res[0] = np.dot(A[0], B[0])
res[1] = np.dot(A[1], B[1])
etc
我可以使用循环成功地实现这一点,例如:

A = np.random.random((5,3,3))
B = np.random.random((5,3))

res = np.zeros([5,3])

for i in range(len(A)):
    res[i] = np.dot(A[i], B[i])
虽然这很慢,因为它使用循环

是否有一种功能/方法可以完全矢量化

谢谢。

您可以使用-

使用-


因为我总是很难理解
einsum()
,所以我提出了以下建议:

np.diagonal(np.squeeze(np.dot(A, B[:,:,None])), axis2=2).T

它可以工作,并且没有循环,但是它比
einsum()
慢得多,因为
:,:,无
B
从2D扩展到3D(稍后减少
对角线()
)。我不确定是否有办法使它更紧凑。

另外,使用sum和broadcasting:

np.sum(A * B[:, np.newaxis, :], axis=2)
不过,Einsum似乎是最快的选择。
这将是最慢的,因为它实例化了元素的乘积。

谢谢。Einsum听起来是最有效的。我只需要弄清楚它现在是如何工作的……有时有比
einsum
更快的张量计算方法,但没有一种更清晰。我曾经像下面的约翰一样是一个怀疑者,但迪瓦卡让我成为了一个信徒。@DanielForsman是的!主要是根据所涉及的输入阵列的形状和总和约化的轴长度进行权衡。这里面有很多游戏,很有趣!在这种情况下,新的
matmul
@
)是一个很大的改进。正如Divakar所示,它仍然需要扩展
B
,但不需要使用
对角线进行大量额外计算<代码>挤压
很便宜。
np.diagonal(np.squeeze(np.dot(A, B[:,:,None])), axis2=2).T
np.sum(A * B[:, np.newaxis, :], axis=2)