为什么numpy.broadcast"转置" vstack和类似功能的结果?

时间:2016-03-27 22:03:07

标签: python arrays numpy numpy-broadcasting

观察:

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]])

同样适用于column_stackrow_stackhstack在这种情况下表现不同,但与广播一起使用时也有所不同)。为什么呢?

我遵循背后的逻辑,而不是找到一种方法来修复"这种行为(我对它很好,它只是不直观)。

1 个答案:

答案 0 :(得分: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+12+23+3添加)。

如果您深入了解vstack的来源,您会发现all it does确保已经给出的迭代元素至少是二维的,然后沿轴堆叠它们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书中找到。