广播在这个 numpy 的例子中是如何应用的?

How is broadcasting applying in this example of numpy?

我正在学习 numpy 并且对广播有点困惑,这是我的设置。我有两个矩阵

>>> y=np.array([1,2,3])
>>> v = np.array([1,2,3])
>>> r=np.reshape(v, (3, 1))

所以 r 是 (3*1) 矩阵,而 y 是 1 阶矩阵,形状为 (3,)。

如果我做 y.dot(r),我得到 14,假设 numpy 在 y 上应用广播,使它成为 (1*3) 然后它用 r(3*1) 做点积所以结果矩阵将是 1*1.

然而,当我执行 r.dot(y) 时,它会抛出错误。为什么它不在这里做同样的事情?它应该使 y(1*3) 和 r 为(3*1),它应该给出一个 3*3 矩阵。这个推理有什么问题?

这就像纸上的矩阵乘法,两个内部维度需要一致。因此,如果您想要 3x3,不仅 r 的形状需要 (3,1),而且 y 的形状需要 (1,3) 而不是 (3,)

像这样:

In [60]: r.dot(y.reshape(1,-1))
Out[60]: 
array([[1, 2, 3],
       [2, 4, 6],
       [3, 6, 9]])

我觉得 numpy 应该推断出这一点,但我猜 "explicit is better than implicit"

正常广播不适用于np.dot。文档说:

For N dimensions it is a sum product over the last axis of a and the second-to-last of b::

y(3,)r(3,1).

y*r中应用广播,y被reshape为(1,3),结果为(3,3).

np.dot(y,r)中,y的最后一个轴是3r的倒数第二个也是3,相乘相加,形状是 (1,)。请注意,如果 y(1,3) 开头,则结果为 2d:

In [445]: np.dot(y.reshape(1,3),r).shape
Out[445]: (1, 1)

np.dot(r,y) 中,r 的最后一个轴是 1y 的倒数第二个(仅)是 3 - 因此不匹配。

扩展 y 会产生 (3,3):

In [449]: np.dot(r,y.reshape(1,3))
Out[449]: 
array([[1, 2, 3],
       [2, 4, 6],
       [3, 6, 9]])