Python自學筆記 | 使用Numpy取代For-Loop
Hey guys~我是阿本
相信大家接觸到程式碼的原因,不外乎是為了能夠更有效率的將資料進行整理與分析。
Python並不是我接觸的第一種程式語言,但其容易學習且社群資源豐富使得Python成為阿本我最常使用的語言。
但隨著資料的不斷增加,Python運行效率低的劣勢就越來越明顯。這也讓我開始尋找提升運行速度的方法。
也好在很多大神整理了不少方法,其中看到Anmol Tomar在Medium的文章Say Goodbye to Loops in Python, and Welcome Vectorization讓我想翻譯整理一下透過矩陣運算取代迴圈,對我們程式運行影響有多大。
在開始之前,不免俗的還是要先來說說Numpy這個模組。
什麼是Numpy?
Numpy是一個用於科學計算的基礎Python函式庫,它提供了許多用於處理多維陣列和矩陣的高效函式。非常適合用於處理向量和矩陣運算,並且可以使用它來輕鬆地進行統計分析、傅里葉轉換(Fourier Transform)、機器學習等應用。資料科學相關的重要套件幾乎都是架構在 Numpy基礎上做應用(像是Pandas、Scikit-learn之類的)。
要安裝Numpy也非常容易,只要在環境內輸入一行指令即可。
# 透過conda安裝 conda install numpy # 透過pip安裝 pip install numpy
將資料向量化與操作迴圈之間的差別
向量化是在數據集上實現 (NumPy)數組操作的技術。它將在背景操作一次性應用於數組或系列的所有元素(不同於一次操作一行的“for”循環)。
Vectorization is the technique of implementing (NumPy) array operations on a dataset. In the background, it applies the operations to all the elements of an array or series in one go (unlike a ‘for’ loop that manipulates one row at a time).
這也就是透過矩陣與迴圈最重要的差異:矩陣運算一次性得透過數組進行運算,而迴圈則是重複對數值進行運算,因此少了大量重複運算使得運算更高效和快速。
我們透過下面這個例子來做比較:如果我們要從0加到15,000,000時,使用迴圈會是這樣:
#使用迴圈計算0+1+2+⋯⋯+150,000,000 total = 0 for item in range(0, 15000000): total = total + item print(total) #output:112499992500000 #花費時間:1.9316秒
而如果是透過Numpy運算,則是:
#使用Numpy陣列計算0+1+2+⋯⋯+150,000,000 #numpy.arange([start, ]stop, [step, ]dtype=None, *, like=None) import numpy as np print(np.sum(np.arange(0,15000000,1))) #output:112499992500000 #花費時間:0.0196秒
我們透過np.arange式子,成功將運算時間從將近兩秒鐘縮短到只要0.02秒就能完成公式,從圖解能夠幫助我們更快了解他們運作的差異。
什麼!你覺得只差1秒差不了多少嗎?那只是還沒進入到更複雜的運算情境而已。
運算情境1:計算各國性別比
世界銀行每年都會公布全球人口數值,剛好手邊有份2021年的人口統計資料(沒有的夥伴可以到The World Bank Data找找看),資料叫入程式內後長這樣:
再來我們要來計算各個國家的性別比,公式長這樣:
性別比=男性人口數/女性人口數X 100
話不多說,我們看看迴圈與矩陣的表現吧
import pandas as pd import numpy as np data=pd.read_csv(r"2021全球人口.csv") #使用迴圈 for idx, row in data.iterrows(): data.at[idx,'sex ratio'] = 100 * (row["Male"] / row["Female"]) #運行時間0.0206秒 #使用矩陣 data["sex ratio"] = 100 * (row["Male"] / row["Female"]) #運行時間0.0009秒
不僅程式只剩一行,運行時間也提升了23倍!
運算情境2:計算各國經濟成長率
經濟成長率通常是一國經濟成長的衡量指標。接下來我們來透過成長率來看看哪些國家在2021年是呈現負成長吧!先上數據:
再來根據兩年的GPD數值進行運算
import pandas as pd import numpy as np data=pd.read_csv(r"2020-2021GPD.csv") #使用迴圈 for idx, row in data.iterrows(): data.at[idx,'GDP_growth'] = 100 * (row["2021"] - row["2020"])/row["2020"] if pd.isna(row.GDP_growth): data.at[idx,'growth'] = '無資料' elif row.GDP_growth > 0: data.at[idx,'growth'] = '正成長' else: data.at[idx,'growth'] = '負成長' #運行時間0.0399 #使用矩陣 data['GDP_growth'] = 100 * (data["2021"] - data["2020"])/data["2020"] data['growth']='無資料' data.loc[data['GDP_growth'] < 0, 'growth'] = '正成長' data.loc[data['GDP_growth'] > 0, 'growth'] = '負成長'
加強運行效率的方法其實非常多,numpy矩陣其實只是其中一種方法而已。
剛好最近稍微整理一下過去自學的筆記,就順便放上來分享一下了。
如果這篇文章剛好幫助到你,請點五下拍手給我些鼓勵,
也歡迎其他大佬們提供其他建議,讓我這個小菜鳥友進步的機會。
那就這樣啦~我是阿本~咱們下次見!
喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!
- 来自作者
- 相关推荐