我希望将数组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
答案 0 :(得分:7)
如果您只想用标量填充数组,fill
可能是最佳选择。但听起来你想要更通用的东西。而不是使用broadcast
,您可以使用broadcast_arrays
来获得您想要的结果(我认为)。
>>> 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
答案 1 :(得分:2)
fill
听起来像最简单的方式:
>>> a = np.arange(9).reshape((3,3))
>>> a
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> a.fill(10)
>>> a
array([[10, 10, 10],
[10, 10, 10],
[10, 10, 10]])
编辑:正如@EOL指出的那样,如果你想创建一个新数组,你不需要arange
,np.empty((100,100))
(或任何形状)更适合此
时序:
In [3]: a = np.arange(10000).reshape((100,100))
In [4]: %timeit 1 + a*0
100000 loops, best of 3: 19.9 us per loop
In [5]: a = np.arange(10000).reshape((100,100))
In [6]: %timeit a.fill(1)
100000 loops, best of 3: 3.73 us per loop
答案 2 :(得分:1)
如果您只需要将标量广播为任意形状,您可以执行以下操作:
a = b*np.ones(shape=(3,3))
编辑:np.tile
更为一般。您可以使用它来复制任意数量的任何标量/向量:
b = 1
N = 100
a = np.tile(b, reps=(N, N))
答案 3 :(得分:1)
我所知道的最快,最干净的解决方案是:
b_arr = numpy.empty(a.shape) # Empty array
b_arr.fill(b) # Filling with one value