[英]Why numpy.where is much faster than alternatives
我試圖加快以下代碼:
import time
import numpy as np
np.random.seed(10)
b=np.random.rand(10000,1000)
def f(a=1):
tott=0
for _ in range(a):
q=np.array(b)
t1 = time.time()
for i in range(len(q)):
for j in range(len(q[0])):
if q[i][j]>0.5:
q[i][j]=1
else:
q[i][j]=-1
t2=time.time()
tott+=t2-t1
print(tott/a)
如您所見,主要是func是關於雙循環迭代。 所以,我試圖使用np.nditer
, np.vectorize
和map
而不是它。 如果給出一些加速(比如np.nditer
除了4-5次),但是! 與np.where(q>0.5,1,-1)
加速幾乎是100x。 我怎樣才能像np.where
那樣快速迭代numpy數組呢? 為什么它這么快?
這是因為numpy的核心是用C實現的。你基本上是將C的速度與Python進行比較。
如果你想使用numpy的速度優勢,你應該在Python代碼中盡可能少地進行調用。 如果使用Python循環,即使只在該循環中使用numpy函數,也已經丟失了。 使用numpy提供的更高級別的功能(這就是他們發布這么多特殊功能的原因)。 在內部,它將使用更高效的(C-)循環
您可以自己在C(帶循環)中實現一個函數,並從Python中調用它。 這應該提供相當的速度。
要回答這個問題,您可以使用numba
庫獲得相同的速度(100倍加速度):
from numba import njit
def f(b):
q = np.zeros_like(b)
for i in range(b.shape[0]):
for j in range(b.shape[1]):
if q[i][j] > 0.5:
q[i][j] = 1
else:
q[i][j] = -1
return q
@njit
def f_jit(b):
q = np.zeros_like(b)
for i in range(b.shape[0]):
for j in range(b.shape[1]):
if q[i][j] > 0.5:
q[i][j] = 1
else:
q[i][j] = -1
return q
比較速度:
純Python
%timeit f(b)
592 ms ± 5.72 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Numba(使用LLVM~C速度進行即時編譯)
%timeit f_jit(b)
5.97 ms ± 105 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.