python - 有没有更好的方法来广播数组?

标签 python numpy array-broadcasting

我想将一个数组 b 广播到它与另一个数组 a 进行算术运算时的形状。

例如,如果 a.shape = (3,3)b 是一个标量,我想得到一个数组,其形状是 (3 ,3) 并填充标量。

一种方法是这样的:

>>> import numpy as np
>>> a = np.arange(9).reshape((3,3))
>>> b = 1 + a*0
>>> b
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])

虽然这实际上可行,但我不禁觉得它看起来有点奇怪,而且对于其他查看代码的人来说我正在尝试做的事情并不明显。

有没有更优雅的方法来做到这一点?我查看了 np.broadcast 的文档,但速度要慢几个数量级。

In [1]: a = np.arange(10000).reshape((100,100))

In [2]: %timeit 1 + a*0
10000 loops, best of 3: 31.9 us per loop

In [3]: %timeit bc = np.broadcast(a,1);np.fromiter((v for u, v in bc),float).reshape(bc.shape)
100 loops, best of 3: 5.2 ms per loop

In [4]: 5.2e-3/32e-6
Out[4]: 162.5

最佳答案

如果您只想用标量填充数组,fill 可能是最佳选择。但听起来你想要更笼统的东西。您可以使用 broadcast_arrays 而不是使用 broadcast 来获得(我认为)您想要的结果。

>>> a = numpy.arange(9).reshape(3, 3)
>>> numpy.broadcast_arrays(a, 1)[1]
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])

这推广到任何两个可广播形状:

>>> numpy.broadcast_arrays(a, [1, 2, 3])[1]
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

它不如基于 ufunc 的方法快,但仍处于同一数量级:

>>> %timeit 1 + a * 0
10000 loops, best of 3: 23.2 us per loop
>>> %timeit numpy.broadcast_arrays(a, 1)[1]
10000 loops, best of 3: 52.3 us per loop

但是标量,fill 仍然是明显的领先者:

>>> %timeit b = numpy.empty_like(a, dtype='i8'); b.fill(1)
100000 loops, best of 3: 6.59 us per loop

最后,进一步的测试表明最快的方法——至少在某些情况下——是乘以ones:

>>> %timeit numpy.broadcast_arrays(a, numpy.arange(100))[1]
10000 loops, best of 3: 53.4 us per loop
>>> %timeit (1 + a * 0) * numpy.arange(100)
10000 loops, best of 3: 45.9 us per loop
>>> %timeit b = numpy.ones_like(a, dtype='i8'); b * numpy.arange(100)
10000 loops, best of 3: 28.9 us per loop

关于python - 有没有更好的方法来广播数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11622692/

相关文章:

python - 如何在多个 Raspberry Pi 3 上同时运行 python 脚本?

python - 使用 numpy.savetxt 实现不同的列格式

python - 手动制作的 3D 卷积神经网络的形状误差

python - scikit-learn - 具有置信区间的 ROC 曲线

python - 弹跳球不会回来pygame

python - 生成具有不同范围的嵌套列表

python - 在 NumPy 数组中为每个唯一元素选择一个随机索引,并考虑引用数组中缺失的元素

使用广播语义进行转置的tensorflow concat

python - sqlalchemy 和 SQLite 共享缓存

python - 按百分比将列表划分为子列表