Python自學筆記 | 使用Numpy取代For-Loop

阿本
·
·
IPFS
·
將運算思維從迴圈轉成向量,能夠加速我們的工作效率

Hey guys~我是阿本

相信大家接觸到程式碼的原因,不外乎是為了能夠更有效率的將資料進行整理與分析。
Python並不是我接觸的第一種程式語言,但其容易學習且社群資源豐富使得Python成為阿本我最常使用的語言。
但隨著資料的不斷增加,Python運行效率低的劣勢就越來越明顯。這也讓我開始尋找提升運行速度的方法。
也好在很多大神整理了不少方法,其中看到Anmol Tomar在Medium的文章Say Goodbye to Loops in Python, and Welcome Vectorization讓我想翻譯整理一下透過矩陣運算取代迴圈,對我們程式運行影響有多大。

在開始之前,不免俗的還是要先來說說Numpy這個模組。

什麼是Numpy?

影像來源:https://numpy.org/

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找找看),資料叫入程式內後長這樣:

2021全球人口.csv

再來我們要來計算各個國家的性別比,公式長這樣:

性別比=男性人口數/女性人口數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年是呈現負成長吧!先上數據:

2020-2021GPD.csv

再來根據兩年的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矩陣其實只是其中一種方法而已。
剛好最近稍微整理一下過去自學的筆記,就順便放上來分享一下了。

如果這篇文章剛好幫助到你,請點五下拍手給我些鼓勵,
也歡迎其他大佬們提供其他建議,讓我這個小菜鳥友進步的機會。

那就這樣啦~我是阿本~咱們下次見!

CC BY-NC-ND 2.0 授权

喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!

阿本@xiang2000021@liker.social 大學剛畢業準備迎接碩士生活 非資工背景出身的程式新手 想有個地方分享自己的學習筆記
  • 来自作者
  • 相关推荐

閒聊隨筆 | 在北投 與老屋書店的相遇

Python自學筆記 | 讓re來整理資料吧

閒聊隨筆 | Liker Social :簡單、自由的中文社群聯邦