取代Pandas?強大的資料分析函式庫Polars! — Polars 10 大功能簡介

加速資料分析工具—Polars 10大功能簡介

Elena
13 min readJul 29, 2023
Source: polars github

相信在資料分析領域,沒有人不知道Pandas,但如果處理的資料量相當大,Pandas真的跑超慢~~~~~~而且numba還不支援Pandas(極少部分函數會支援),完全無法加速作業啊!

然而,Polars的出現可以解決你的困擾並增加資料處理的效率!Polars用Apache Arrow作為其底層資料結構,並使用Rust語言開發實現。此外,Polars利用多執行緒操作來並行處理計算,這種並行處理能夠顯著加快對大型資料集的操作。

或許你還對Polars不熟悉,但其實有Pandas的先備知識,可以非常快速上手!本篇將介紹Polars的十大功能並和Pandas做比較,效率上的比較則會在下一篇呈現。

Polars十大功能,已整理在Github

  1. 創建一個DataFrame Polars.DataFrame()
  2. 取得前n筆及後n筆的資料 DataFrame.tail(n) , DataFrame.head(n)
  3. 取得某欄(行)資料 DataFrame.select() , DataFrame.get_column(name)
  4. 取得某列資料 DataFrame.row(index)
  5. 取得特定位置的值 DataFrame.item(row, column)
  6. 篩選資料 DataFrame.filter()
  7. 新增DataFrame資料 Polars.concat()
  8. 計算某欄位各個值的個數 polars.Expr.value_counts()
  9. 組成群組及聚合函數 DataFrame.groupby() , GroupBy.agg()
  10. 對某欄的值進行計算或處理 DataFrame.apply()

Let’s Start !

1. 創建一個DataFrame

Polars.DataFrame()

相信使用過Pandas 的都不陌生,創建一個DataFrame可以建立字典、list或numpy的方式,Polars也是一樣。我們創建一個4位不同工作的字典,包含姓名、地區、薪水、工作,接下來我們輸出看看polars和pandas的差別。

data = {
"Name":["Joyce", "Elena", "Judy", "Mindy"],
"County": ["Taipei", "Taichung", "Yilan", "Tainan"],
"Salary": [55000, 70000, 48000, 50000],
"Job":["Data analyst", "ML engineer", "Servant", "Project Manager"]
}
pd_df = pd.DataFrame(data)
pl_df = pl.DataFrame(data)
print("================== Pandas ==================")
print(pd_df)
print()
print("================== Polars ==================")
print(pl_df)

可以發現不同處是Polars的輸出有外框,強迫症的人看了可能會覺得蠻舒服的~再來可以注意Pandas會給定每個row的index,而Polars則沒有。另外,Polars的輸出會顯示每個Column的data type,在資料分析data type是很重要的事,直接顯示真的不用一欄一欄print了!

結果如下:

2. 取得前n筆及後n筆的資料

DataFrame.tail(n) , DataFrame.head(n)

要取得DataFrame前兩筆或後兩筆的資料,polars跟pandas一樣是使用head()tail()來取得。

print("================== Pandas ==================")
print("* head function")
print(pd_df.head(2))
print()
print("* tail function")
print(pd_df.tail(2))
print()
print("================== Polars ==================")
print("* head function")
print(pl_df.head(2))
print()
print("* tail function")
print(pl_df.tail(2))

結果如下:

3. 取得某欄(行)資料

DataFrame.select() , DataFrame.get_column(name)

Pandas 取某欄位的資料,可以直接用標題名稱取得該欄資訊;Polars用selectget_column的方式給定標題名稱來取對應的欄位資訊。注意select返回的type為DataFrame,而get_column 返回的是Series。

print("================== Pandas ==================")
print(pd_df['Salary']) ## type: Series
print()
print(pd_df.loc[:, 'Salary']) # Series
print()
print("================== Polars ==================")
print(pl_df.select('Salary')) # DataFrame
print()
print(pl_df.get_column('Salary')) # Series

結果如下:

4. 取得某列資料

DataFrame.row(index)

在Pandas,想要取得某列的資料,我們可以用ilocloc 的方式,iloc給定索引值,loc則可給定欄位名稱取值,返回的型別是Series。Polars沒有列的index概念,因此沒有loc的用法,可以用DataFrame.row(),取得某列資料的值(不會有欄位名稱),為tuple形式,如果想要獲得各值對應的欄位,可以加named = True ,他會以字典儲存資訊。

print("================== Pandas ==================")
print(pd_df.iloc[2]) #Series
print()
print(pd_df.loc[2]) #Series
print()
print("================== Polars ==================")
print(pl_df.row(2))
print(pl_df.row(2, named = True))

結果如下:

5. 取得特定位置的值

DataFrame.item(row, column)

使用Pandas可以用iat[] 來找到第幾列第幾行的某個值,Polars則是用item() 來獲得單一值。

print("================== Pandas ==================")
print(pd_df.iat[1,1])
print("================== Polars ==================")
print(pl_df.item(1,1))

結果如下:

6. 篩選資料

DataFrame.filter()

資料分析時,常會需要找到符合某些條件的資訊,如我想要找到薪水小於等於五萬且位在台南工作的人,來看看Pandas和Polars的差別。

print("================== Pandas ==================")
multi_filter_pd_df = pd_df[(pd_df.Salary <= 50000) & (pd_df.County == "Tainan")]
print(multi_filter_pd_df)
print()
print("================== Polars ==================")
multi_filter_pl_df = pl_df.filter((pl.col("Salary") <= 50000) & (pl.col("County") == "Tainan"))
print(multi_filter_pl_df)

結果如下:

7. 新增DataFrame資料

Polars.concat()

Pandas的concat可以合併多個DataFrame,組成一個新的DataFrame,Polars也是一樣的用法。現在要新增一位Marcus的資訊,先建立新的DataFrame儲存資訊,再將兩個DataFrame合併。

print("================== Pandas ==================")
pd_df2 = pd.DataFrame({
"Name": ["Marcus"],
"County": ["Taipei"],
"Salary": [60000],
"Job": ["Survey Engineer"]
})
new_pd_df = pd.concat([pd_df, pd_df2])
print(new_pd_df)
print()
print("================== Polars ==================")
pl_df2 = pl.DataFrame({
"Name": "Marcus",
"County": "Taipei",
"Salary": 60000,
"Job": "Survey Engineer"
})
new_pl_df = pl.concat([pl_df, pl_df2])
print(new_pl_df)

結果如下:

8. 計算某欄位各個值的個數

polars.Expr.value_counts()

想要取得County這欄位所出現的值的個數,可以用value_counts() 來獲得。

print("================== Pandas ==================")
print(new_pd_df.value_counts("County"))
print()
print("================== Polars ==================")
print(new_pl_df.select(pl.col("County").value_counts(sort=True)))

結果如下:

9. 組成群組及聚合函數

DataFrame.groupby() , GroupBy.agg()

群組化資料是資料分析很常使用的工具,可以知道各群組中的欄位資訊或是藉由分組來檢視其他欄位的資料。群組功能很常跟聚合函數一起使用,可以對欄位數值進行運算,以獲得有效的數值分析。

首先群組"County"欄位,想要知道各縣市群組的最低薪資、最高薪資、平均薪資、薪資中位數,做法如下所示:

print("================== Pandas ==================")
group = new_pd_df.groupby(['County'])
print(group.get_group('Taipei'))
print()
print(group['Salary'].aggregate(['min', 'max', 'mean', 'median']))
print()
print("================== Polars ==================")
group_pl_df = new_pl_df.groupby('County').agg([pl.col('Salary').min().alias("min"), pl.col('Salary').max().alias("max")
,pl.col('Salary').mean().alias("mean"), pl.col('Salary').median().alias("median")
])
print(group_pl_df)

💡 ailas :改column名字避免覆寫已存在的欄位名

結果如下:

10. 對某欄的值進行計算或處理

DataFrame.apply()

apply在Pandas是常見資料處理的方法,可以對某欄位的值進行處理。Polars也有apply函數可以使用,用法也相似。如我想對"Salary"欄位乘以1.5倍,並且"County"欄位的值多加”City”,做法如下所示,但比較起來Polars用法好像較為直觀,或許可以留言給我Pandas的用法要再怎麼精簡~

print("================== Pandas ==================")
new_pd_df["Salary"], new_pd_df["County"] = new_pd_df["Salary"].apply(lambda x: x * 1.5), new_pd_df["County"].apply(lambda x: x + " City")
print(new_pd_df[["Salary", "County"]])
# print(new_pd_df.apply(lambda t: (int(t[2]) * 1.5, t[1] + " City")))
print()
print("================== Polars ==================")
print(new_pl_df.apply(lambda t: (t[2] * 1.5, t[1] + " City")))

結果如下:

小結:

整理完發現其實Polars的用法跟Pandas相似,上手很快,如果我要處理大筆資料,或許我會使用Polars!下一篇有速度上的比較,處理速度真的差非常多啊!

以上統整Polars 十大用法,喜歡這篇文章別忘了幫我的文章 👏,如果文章有錯誤的地方歡迎留言指教~

--

--

Elena

AI Engineer | Data | GIS | 金魚腦女子,希望可以透過文字記錄以喚起被遺忘的記憶。