<pre><code>In [321]: vec1=np.array([0,0.5,1,0.5]); vec2=np.array([2,0.5,1,0.5])
...: vec=np.transpose(np.stack((vec1,vec2)))
In [322]: vec1.shape
Out[322]: (4,)
In [323]: vec.shape
Out[323]: (4, 2)
</code></pre>
<p><code>stack</code>函数的一个优点是我们可以指定一个轴,跳过转置:</p>
^{pr2}$
<p>为什么<code>np.</code>和{<cd3>}的混合?<code>NameError: name 'n' is not defined</code>。那种事差点把我送走。在</p>
<pre><code>In [326]: mat = np.moveaxis(np.array([[[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3]],[[-1,2.,0
...: ,1.],[0,0,-1,2.],[0,1,-1,2.],[1,0.1,1,1]]]),0,2)
In [327]: mat.shape
Out[327]: (4, 4, 2)
In [328]: outvec=np.zeros((4,2))
...: for i in range(2):
...: outvec[:,i]=np.dot(mat[:,:,i],vec[:,i])
...:
In [329]: outvec
Out[329]:
array([[ 4. , -0.5 ],
[ 4. , 0. ],
[ 4. , 0.5 ],
[ 4. , 3.55]])
In [330]: # (4,4,2) (4,2) 'kji,ji->ki'
</code></pre>
<p>在循环中,<code>i</code>轴(大小2)的位置在所有3个数组中都是最后一个。只留下一个轴给<code>vec</code>,我们将其称为<code>j</code>。它与最后一个(紧挨着<code>i</code>的<code>mat</code>)配对。<code>k</code>从<code>mat</code>转移到{<cd12>}。在</p>
<pre><code>In [331]: np.einsum('kji,ji->ki', mat, vec)
Out[331]:
array([[ 4. , -0.5 ],
[ 4. , 0. ],
[ 4. , 0.5 ],
[ 4. , 3.55]])
</code></pre>
<p>通常,<code>einsum</code>字符串会自己写入。例如,<code>mat</code>被描述为(m,n,k),而{<cd6>}被描述为(n,k),结果是(m,k)</p>
<p>在本例中,只有<code>j</code>维被求和-它出现在左边,但在右边。最后一个维度,<code>i</code>在我的符号中,没有求和,因为if出现在两边,就像在迭代中一样。我认为这是“顺其自然”。它不是<code>dot</code>产品的积极组成部分。在</p>
<p>实际上,你是在最后一个维度上堆积,尺寸2。通常我们把第一个放在第一个上,但是你把两者都换过来放最后一个。在</p>
<hr/>
<p>您的“失败”尝试运行,并且可以复制为:</p>
<pre><code>In [332]: np.einsum('ijk,il->ik', mat, vec)
Out[332]:
array([[12. , 4. ],
[ 6. , 1. ],
[12. , 4. ],
[ 6. , 3.1]])
In [333]: mat.sum(axis=1)*vec.sum(axis=1)[:,None]
Out[333]:
array([[12. , 4. ],
[ 6. , 1. ],
[12. , 4. ],
[ 6. , 3.1]])
</code></pre>
<p><code>j</code>和<code>l</code>维度没有出现在右侧,因此它们被相加。它们可以在相乘之前求和,因为它们只出现在一个项中。我添加了<code>None</code>以启用广播(将<code>ik</code>与<code>i</code>相乘)。在</p>
<pre><code>np.einsum('ik,i->ik', mat.sum(axis=1), vec.sum(axis=1))
</code></pre>
<hr/>
<p>如果在第一个上堆叠,并为<code>vec</code>(2,4,1)添加一个维度,那么它将使用一个(2,4,4)mat <code>matmul</code>。<code>mat @ vec[...,None]</code>。在</p>
<pre><code>In [337]: m1 = mat.transpose(2,0,1)
In [338]: m1@v1[...,None]
Out[338]:
array([[[ 4. ],
[ 4. ],
[ 4. ],
[ 4. ]],
[[-0.5 ],
[ 0. ],
[ 0.5 ],
[ 3.55]]])
In [339]: _.shape
Out[339]: (2, 4, 1)
</code></pre>