Numpy 广播 - 需要完全理解

问题描述 投票:0回答:1

我正在尝试了解 Numpy 广播。

所以我想了解为什么下面的代码可以工作?

a = np.arange(4).reshape(2,2)
b = np.arange(6).reshape(3,2)

a = a[:, np.newaxis]

a + b

我的意思是,如果我们尝试添加 a 和 b 而不添加另一个维度,则会抛出 ValueError。 “ValueError:操作数无法与形状 (2,2) (3,2) 一起广播”

但是如果我们使用 newaxis 来给 a 增加一个维度,形状仍然不同,为什么会这样呢?为什么 NumPy 尝试对不同维度和形状的数组执行算术运算时不会抛出错误。

还有一个明确的资源可以通过详尽的示例列表深入解释 Numpy 广播吗?

根据以下链接中给出的解释添加尺寸后 我如何使用np.newaxis? - kmario23的解释场景2。它似乎有效。但我的理解是,如果形状不同,那么它就不应该起作用。

python numpy multidimensional-array array-broadcasting
1个回答
0
投票
In [2]: a = np.arange(4).reshape(2,2)
   ...: b = np.arange(6).reshape(3,2)
   ...: 
   ...: a = a[:, np.newaxis]; a.shape
Out[2]: (2, 1, 2)

In [3]: c=a+b; c.shape
Out[3]: (2, 3, 2)

有2条基本规则

  • 如果维度数不同,请根据需要添加前导大小 1 维度,以便它们匹配

  • 缩放所有尺寸 1 尺寸以匹配;通常这意味着扩大规模,但扩大到 0 也是可能的

在这里您明确添加了一个维度,作为第二个维度。所以在

a+b
中,我们有 (2,1,2) 和 (3,2)。

根据规则一,(3,2) 扩展为 (1,3,2)

根据规则二,两者都缩放为 (2,3,2)。

为了进一步详细说明,向

b
添加主尺寸可以:

In [6]: b = b[None,:,:]; b.shape, b.strides
Out[6]: ((1, 3, 2), (0, 8, 4))

为了比较,

a.strides
是:

In [7]: a.shape, a.strides
Out[7]: ((2, 1, 2), (8, 0, 4))

注意 1 尺寸的步幅为 0。在幕后,正是 0 步幅使其能够缩放尺寸。

对于高级索引,广播的工作方式相同。

但是对于赋值和

+=
类型的操作,LHS无法调整,所以广播的应用略有不同。

© www.soinside.com 2019 - 2024. All rights reserved.