<p><code>np.dot</code>是矩阵乘法的推广。
在正则矩阵乘法中,(N,M)形矩阵与(M,P)形矩阵相乘得到(N,P)形矩阵。合成的形状可以认为是通过将两个形状挤压在一起(<code>(N,M,M,P)</code>),然后去掉中间的数字<code>M</code>(产生<code>(N,P)</code>)而形成的。这是<code>np.dot</code>在泛化到高维数组时保留的属性。</p>
<p>当医生说</p>
<blockquote>
<p>"For N dimensions it is a sum product over the last axis of a and the
second-to-last of b".</p>
</blockquote>
<p>这正说明了这一点。一个以形状数组<code>(u,v,M)</code>点缀的形状数组<code>(w,x,y,M,z)</code>将产生一个形状数组<code>(u,v,w,x,y,z)</code>。</p>
<hr/>
<p>让我们看看这个规则应用于</p>
<pre><code>In [25]: V = np.arange(2); V
Out[25]: array([0, 1])
In [26]: M = np.arange(4).reshape(2,2); M
Out[26]:
array([[0, 1],
[2, 3]])
</code></pre>
<p>首先,简单的部分:</p>
<pre><code>In [27]: np.dot(M, V)
Out[27]: array([1, 3])
</code></pre>
<p>这并不奇怪,这只是矩阵向量乘法。</p>
<p>现在考虑一下</p>
<pre><code>In [28]: np.dot(V, M)
Out[28]: array([2, 3])
</code></pre>
<p>看V和M的形状:</p>
<pre><code>In [29]: V.shape
Out[29]: (2,)
In [30]: M.shape
Out[30]: (2, 2)
</code></pre>
<p>所以<code>np.dot(V,M)</code>就像是(2,)-形矩阵与(2,2)形矩阵的矩阵乘法,结果应该是(2,)-形矩阵。</p>
<p>将<code>V</code>的最后(也是唯一)轴和<code>M</code>的第二个到最后一个轴(也称为<code>M</code>的第一个轴)相乘和相加,只留下<code>M</code>的最后一个轴。</p>
<p>如果您想可视化这个:<code>np.dot(V, M)</code>看起来V有1行2列:</p>
<pre><code>[[0, 1]] * [[0, 1],
[2, 3]]
</code></pre>
<p>所以,当V乘以M时,<code>np.dot(V, M)</code>等于</p>
<pre><code>[[0*0 + 1*2], [2,
[0*1 + 1*3]] = 3]
</code></pre>
<p>然而,我并不建议尝试以这种方式可视化NumPy数组——至少我从来没有这样做过。我几乎只关注形状。</p>
<pre><code>(2,) * (2,2)
\ /
\ /
(2,)
</code></pre>
<p>你只需想想“中间”轴被点着,然后从结果形状中消失。</p>
<hr/>
<p><code>np.sum(arr, axis=0)</code>告诉NumPy对第0轴中的元素进行求和。如果<code>arr</code>是二维的,则第0个轴是行。例如,如果<code>arr</code>看起来像这样:</p>
<pre><code>In [1]: arr = np.arange(6).reshape(2,3); arr
Out[1]:
array([[0, 1, 2],
[3, 4, 5]])
</code></pre>
<p>然后<code>np.sum(arr, axis=0)</code>将沿着列求和,从而消除第0个轴(即行)。</p>
<pre><code>In [2]: np.sum(arr, axis=0)
Out[2]: array([3, 5, 7])
</code></pre>
<p>3是0+3的结果,5等于1+4,7等于2+5。</p>
<p>注意<code>arr</code>有形状(2,3),求和后,第0轴被<em>移除</em>,因此结果是形状(3,)。第0轴的长度为2,每个和由添加这2个元素组成。形状(2,3)“变成”(3,)。你可以提前知道结果形状!这有助于引导你的思维。</p>
<p>要测试您的理解,请考虑<code>np.sum(arr, axis=1)</code>。现在1轴被移除。结果的形状是<code>(2,)</code>,结果中的元素是3个值的和。</p>
<pre><code>In [3]: np.sum(arr, axis=1)
Out[3]: array([ 3, 12])
</code></pre>
<p>3等于0+1+2,12等于3+4+5。</p>
<hr/>
<p>所以我们看到对一个轴进行求和可以从结果中消除这个轴。这与<code>np.dot</code>有关,因为<code>np.dot</code>执行的计算是产品的<em>和</em>之和。由于<code>np.dot</code>沿某些轴执行求和操作,因此将从结果中删除该轴。这就是为什么对形状(2,)和(2,2)的数组应用<code>np.dot</code>会得到形状(2,)的数组。两个数组中的前2个相加,消除了这两个数组,只剩下第二个数组中的第二个2。</p>