Numpy學習筆記一——Numpy可以提高陣列重複計算的速度
阿新 • • 發佈:2019-02-15
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倍!