Giv*_*Alz 6 python arrays numpy numpy-broadcasting
今天,我发现代码中有些奇怪的地方,发现在某些情况下它会执行以下命令:
my_list = [0] + np.array([])
Run Code Online (Sandbox Code Playgroud)
结果my_list如下:
array([], dtype=float64)
Run Code Online (Sandbox Code Playgroud)
一开始我很困惑,比我理解的解释器要先将列表转换为一个numpy数组,然后再尝试广播操作:
>>> np.array([0]) + np.array([])
array([], dtype=float64)
Run Code Online (Sandbox Code Playgroud)
我对此行为有一些疑问:
感谢您的澄清!
首先:
如果 python 抛出错误,至少对于列表被转换并消失的特殊情况,不是更好吗?
我认为这个测试是不可能的。根据这个评论:
对于像这样的反向操作
b.__radd__(a)我们调用相应的ufunc。
这意味着 using[0] + np.array([])实际上会调用 ufunc np.add([0], np.array([])),它将类似数组的列表转换为数组,而没有机会决定操作数的大小。
所以广播是给定的。(1,)那么问题是拥有形状并(0,)广播到是否明智(0,)。您可以这样想:标量总是广播,并且在大多数情况下,1 元素一维数组与标量一样好:
>>> np.add([0], [])
array([], dtype=float64)
>>> np.add(0, [])
array([], dtype=float64)
Run Code Online (Sandbox Code Playgroud)
如果您以这种方式看待它,那么它通常是有意义的,尽管我同意这令人惊讶,特别是非单长度数组不会像这样广播。但这不是一个错误(只是一个功能的有趣情况)。
更准确地说,广播发生的事情始终是“大小为 1 的维度将广播”。类似数组[0]具有 shape (1,),并且np.array([])具有 shape (与具有 shape 的(0,)标量相反!)。因此广播发生在单例上,结果具有形状。np.int64()()(0,)
如果我们注入更多的单例维度,它会变得更清楚:
>>> ([0] + np.array([])).shape
(0,)
>>> ([[0]] + np.array([])).shape
(1, 0)
>>> ([[[0]]] + np.array([])).shape
(1, 1, 0)
>>> np.shape([[[0]]])
(1, 1, 1)
Run Code Online (Sandbox Code Playgroud)
因此,例如在最后一种情况下,形状(1, 1, 1)将很好地沿其最后一个维度与一维数组一起广播,并且结果确实应该(1, 1, 0)在这种情况下。
| 归档时间: |
|
| 查看次数: |
91 次 |
| 最近记录: |