1. 程式人生 > >Numpy學習筆記一——Numpy可以提高陣列重複計算的速度

Numpy學習筆記一——Numpy可以提高陣列重複計算的速度

Numpy可以提高陣列重複計算的速度

Numpy陣列的運算速度要比python陣列的運算的快很多,其關鍵是利用向量化操作,通常這在Numpy的通用函式(ufun)中實現。

我們先看看python原生實現對一個數組所有元素取倒數操作的時間效率。這裡使用Ipython的魔術方法%timit計算該操作執行的時間:

In [1]:
import numpy as np
np.random.seed(0)

def compute_reciprocals(values):
    output = np.empty(len(values))
    for i in range(len(values)):
        output[i] = 1.0
/ values[i] return output big_array = np.random.randint(1, 100, size=10 ** 6) %timeit compute_reciprocals(big_array) Out[1]: 1.46 s ± 9.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

以上這種實現方式對於有C語言和Java背景的人來說非常自然,但在python中,這一操作就相當耗時,僅僅是完成百萬次上述操作並存儲結果花了幾秒鐘的時間。事實上,這裡的運算瓶頸並不是運算本身,而是Cpython在每次迴圈時必須做資料型別的檢查和函式的排程。每次進行倒數運算時,python首先檢查物件的型別,並且動態查詢可以使用該資料型別的正確函式。如果我們在編譯程式碼時進行這樣的操作,那麼就能在程式碼執行之前知曉型別的宣告,結果的計算也會更加有效率。

numpy的解決方法

Numpy為很多型別的操作提供了非常方便的、靜態型別的、可編譯程式的藉口,也被稱作向量操作,這種向量方法將迴圈推送至Numpy之下的編譯層,從而取得更快的執行效率。因此,當你看到python指令碼的出現複雜度很高的迴圈時,就應該考慮能否用向量方式替換這個迴圈。

In[2]:%timeit (1.0 / big_array)

Out[2]:
1.46 ms ± 30 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

可以看到,使用向量操作後,對於相同的操作,numpy下執行速度要比python原生方法提升1000倍!