為什麼要用 Numpy?

只用Python不好嗎?

Hsin-Cheng Chao
4 min readDec 31, 2017

前言

這是我學習 Deep Learning Specialization 系列課程的心得筆記,其他相關的心得我會陸續整理在 學習深度學習的課堂筆記 底下

正文

Data scientist 常用的工具組合

在開始學習Machine Learning 之前我就是一個Python的重度使用者,開始學習ML之後我才接觸到Jupyter notebook跟Numpy這兩項工具。一開始有些不習慣,但久了之後覺得這個組合實在是非常方便。不過有一個問題一直令我非常不理解…

為什麼做資料分析的人都不喜歡寫 for loop?

Numpy在做數學(向量,矩陣)運算上提供了非常多方便的語法,例如向量的內積,如果要自己用for loop來做會很麻煩:

VEC_LENGTH = 100000
w = np.random.rand(VEC_LENGTH)
x = np.random.rand(VEC_LENGTH)
# for loop
c = 0
for i in range(VEC_LENGTH):
c += w[i] * x[i]
# numpy
import numpy as np
c = np.dot(w, x)

numpy版本是不是簡單又清楚呢?除了向量內積以外,許多常用的運算也有很好的支援,例如矩陣乘法

A = np.array([
[1, 2, 3],
[2, 3, 4],
])
B = np.array([
[2],
[0],
])
A * B
# array([[2 4 6], [0 0 0]])

或是對矩陣內的每一個項目進行操作

A = np.array([1, 2, 3])
A ** 2
# array([1, 4, 9])

但除了這些 API簡單好用之外,使用Numpy跟自己寫的for loop有一個最關鍵的差別,那就是執行的效能!!我在Jupyter notebook上面做了簡單的實驗,結果如下:

VEC_LENGTH = 100000
w = np.random.rand(VEC_LENGTH)
x = np.random.rand(VEC_LENGTH)

tic = time.time()
c = 0
for i in range(VEC_LENGTH):
c += w[i] * x[i]
toc = time.time()
print('For loop took: %s ms' % str(1000 * (toc - tic)))
# >> For loop took: 124.56703186 mstic = time.time()
c = np.dot(w, x)
toc = time.time()
print('Vectorized dot took: %s ms' % str(1000 * (toc - tic)))
# >> Vectorized dot took: 0.262975692749 ms

124.5670 ms vs 0.2529ms !!快要五百倍的速度提升,五百倍!!這樣的速度提升在其他Numpy API 也都有類似的情形(可以參考這個Notebook)。

這揪~竟~是為什麼呢??

原來Numpy除了幫我們把結果正確算出來之外,會透過硬體裝置(GPU or CPU)來進行加速運算。因此當我們把原本要交給同一個CPU的運算改成透過GPU上面好多個運算單元來同時進行就可以達到這樣的效果了 💪 💪

另外值得一提的是就算電腦沒有安裝GPU,Numpy 還是可以透過SIMD (Single Instruction, Multiple Data) 這種CPU內建的機制來達成加速,因此不論如何使用Numpy就是比自己寫 for loop快上許多。

電競GPU都長得超帥的 😅

結論

對於認真想把是資料處理當飯吃的人來說,五百倍的加速是跑一小時得到結果跟一個月的差別… 如果沒有特別注意很容易就不小心在程式碼裡面寫了低效能的Code而不自知 🙁 所以要非常小心。

最簡單無腦的原則就是:

除非萬不得已,不然不要用 for loop來做資料處理。

以上就是這部分的心得。謝謝您閱讀到最後。想看更多我上課的心得可以參考我學習深度學習的課堂筆記

--

--

Hsin-Cheng Chao
Hsin-Cheng Chao

Written by Hsin-Cheng Chao

Full-stack python engineer by day, Self-Driving Car student by night!

Responses (1)