5

观察:

In [1]: import numpy as np
In [2]: x = np.array([1, 2, 3])
In [3]: np.vstack([x, x])
Out[3]: 
array([[1, 2, 3],
       [1, 2, 3]])

In [4]: np.vstack(np.broadcast(x, x))
Out[4]: 
array([[1, 1],
       [2, 2],
       [3, 3]])

同样 forcolumn_stackrow_stack(hstack在这种情况下表现不同,但与广播一起使用时也不同)。为什么?

我追求这背后的逻辑,而不是找到一种“修复”这种行为的方法(我对此很好,只是不直观)。

4

1 回答 1

5

np.broadcast返回一个迭代器对象的实例,该对象描述了如何一起广播数组。1除其他外,它还描述了结果数组将具有的形状和维数。

至关重要的是,当您在 Python 中实际迭代此对象时,您会从每个输入数组中获取元素元组:

>>> b = np.broadcast(x, x)
>>> b.shape
(3,)
>>> b.ndim
1
>>> list(b)
[(1, 1), (2, 2), (3, 3)]

这告诉我们,如果我们对数组(例如,x+x)执行实际操作,NumPy 将返回一个形状(3,)为一维的数组,并组合元组中的元素以生成最终数组中的值(例如,它将执行1+1, 2+2,3+3用于添加)。

如果你深入挖掘你的源头,vstack你会发现它所做的只是确保给定它的可迭代元素至少是二维的,然后将它们沿轴 0 堆叠。

在这种情况下b = np.broadcast(x, x),我们将以下数组放入堆栈:

>>> [np.atleast_2d(_m) for _m in b]
[array([[1, 1]]), array([[2, 2]]), array([[3, 3]])]

然后将这三个小阵列垂直堆叠,产生您注意到的输出。


1究竟如何并行迭代不同维度的数组是 NumPy 广播工作方式的核心。代码主要可以在iterators.c中找到。Travis Oliphant 自己编写的 NumPy 多维迭代器的有趣概述可以在Beautiful Code书中找到。

于 2016-03-27T22:41:32.533 回答