2017-08-01 101 views
3

目前我使用numpy的点积(3D倍2D)

Na = (3, 2, 4) 
Nb = Na[1:] 
A = np.arange(np.prod(Na)).reshape(Na) 
b = np.arange(np.prod(Nb)).reshape(Nb) 

我想要计算:

r_ik = sum_j(A_ijk * b_jk)

r = np.empty((A.shape[0], A.shape[2]) 
for i in range(A.shape[2]): 
    r[:, i] = np.dot(A[:, :, i], b[:, i]) 

在词:A是“的4堆矩阵“(形状(3,2)),即3d阵列,b是”4个矢量的叠加“(形状(3,)),即2d阵列。期望的结果是“4个矩阵向量积的堆叠”,即向量堆栈,即再次是2d阵列(整形(3,4))。

我对np.einsum和np.tensordot有深入的了解,但是使用这些解决方案构建的解决方案至少和我的循环解决方案一样长且不易读。

但我认为应该有一个简单的问题单线程。

回答

5

我不确定为什么np.einsum不适合你。这应该做的伎俩:

r = np.einsum('ijk,jk->ik', A, b) 

我认为这是非常具有可读性,因为它准确地反映了你在你的问题已经给数学公式。

+0

确实有效。我很困惑的表述是“每当一个标签被重复,它总结出来”(爱因斯坦文档)。我只需要一个总和,但是重复“j”和“k”。因此,我只尝试了'np.einsum('ijk,jl-> ik',A,b)' – basweber

+1

几段进一步说'输出'索引'允许在需要时不允许求和或强制求和'。在输出中放入'k'将关闭它的总和,并且它只是“顺其自然”。 – hpaulj