为什么 numpy.broadcast "transpose" vstack 和类似函数的结果?

Why does numpy.broadcast "transpose" results of vstack and similar functions?

观察:

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_stack 类似(hstack 在这种情况下表现不同,但在与广播一起使用时也不同)。为什么?

我追求的是其背后的逻辑,而不是寻找一种方法来实现 "repairing" 这种行为(我觉得很好,只是不直观)。

np.broadcast returns 描述如何数组应该一起广播的迭代器对象实例。1 其中,它描述了结果数组的形状和维数。

至关重要的是,当你在 Python 中实际 迭代 这个对象时,你会从每个输入数组中得到元素的元组:

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

这告诉我们,如果我们对数组执行实际操作(例如,x+x),NumPy 将 return 一个形状为 (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. An interesting overview of NumPy's multidimensional iterator, written by Travis Oliphant himself, can be found in the Beautiful Code 书中找到。