[英]Is there a better way to broadcast arrays?
我想將數組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
的文檔,但它的速度要低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
數組, 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
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
如果你只需要將標量廣播到某個任意形狀,你可以這樣做:
a = b*np.ones(shape=(3,3))
編輯: np.tile
更通用。 您可以使用它來復制任意數量的任何標量/向量:
b = 1
N = 100
a = np.tile(b, reps=(N, N))
我所知道的最快,最干凈的解決方案是:
b_arr = numpy.empty(a.shape) # Empty array
b_arr.fill(b) # Filling with one value
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.