[英]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.