簡體   English   中英

為什么numpy.where比替代品快得多

[英]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.nditernp.vectorizemap而不是它。 如果給出一些加速(比如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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM