Pandas對比Polars,語法和速度大PK
Pandas是數(shù)據科學中必不可少的Python庫。但其最大的缺點是對大型數(shù)據集的操作速度較慢。Polars是一種旨在更快地處理數(shù)據的Pandas替代方案。
Polars是一種旨在更快地處理數(shù)據的Pandas替代方案。
本文簡要介紹了Polars Python包,并將其與流行的數(shù)據科學庫Pandas在語法和速度方面進行了比較。
- 什么是Polars,為什么它比Pandas更快?
- 基準測試設置
- 開始使用Polars
- Pandas和Polars的比較
- ° 讀取數(shù)據
- ° 選擇和過濾數(shù)據
- ° 創(chuàng)建新列
- ° 分組和聚合
- ° 缺失數(shù)據
- 結論
本文的相關代碼可在Kaggle Notebook中找到,鏈接如下:https://www.kaggle.com/code/iamleonie/pandas-vs-polars
什么是Polars,為什么它比Pandas更快?
根據Polars的用戶指南[1],其目標是“提供一個利用計算機上所有可用核心的閃電般快速的DataFrame庫?!?/p>
與Polars不同,Pandas不會在計算機核心之間進行原生的并行處理。其他工具如Dask是建立在Pandas庫的基礎上嘗試進行并行處理。相反,Polars是專為并行化而設計的,并從頭開始搭建。雖然它是用Rust編寫的,但Polars有一個Python包,這使得它成為Pandas的潛在替代方案。
Polars有兩種不同的API:急切API和惰性API。
急切的執(zhí)行方式類似于Pandas。這意味著直接運行代碼,并立即返回結果。
另一方面,惰性執(zhí)行是在你需要結果時才運行。由于它避免了運行不必要的代碼,因此惰性執(zhí)行可以比急切執(zhí)行更高效。
對于惰性執(zhí)行,必須使用.lazy()方法開始操作。然后可以為你想做的任何事情編寫要執(zhí)行的代碼。最后需要運行.collect()方法來顯示結果。
df.lazy()
.with_columns([(pl.col("col") * 10).alias("new_col")])
#...
.collect()
如果你不運行.collect()方法,則不會立即執(zhí)行操作。相反,你將看到執(zhí)行圖。
圖片
基準測試設置
本基準測試設置使用了一個虛構的數(shù)據集,其中包含每種數(shù)據類型的一列。為了減少時間上的噪聲以便進行比較,該虛構數(shù)據集包含400萬行,幾乎有1GB大小,正如[2]中建議的那樣。
圖片
用于比較Pandas和Polars基準測試的虛構數(shù)據集頭部
在下文中,我們將使用%%timeit -n32 -r4對執(zhí)行進行計時。
開始使用Polars
要設置Polars,只需使用pip安裝它。
pip install polars
之后,可以像使用Pandas一樣導入Polars Python包。
import polars as pl
import pandas as pd
現(xiàn)在,準備工作都已完成。
Pandas和Polars的比較
Pandas和Polars(急切API)在語法方面看起來很相似,因為它們具有共享的主要搭建模塊:Series和DataFrames。
此外,Polars中的許多表達式也與Pandas表達式相似:
# 適用于Pandas和Polars的示例表達式
df.head() # 獲取前n行的數(shù)據
df.tail() # 獲取最后n行的數(shù)據
df.unique() # 獲取此表達式的唯一值。
但是,根據Polars用戶指南[1],“如果你的Polars代碼看起來像是Pandas代碼,它可能會運行,但很可能比它應該運行的速度慢?!?/p>
本節(jié)將探討Polars包在語法和執(zhí)行時間方面與Pandas的主要不同之處:
- 讀取數(shù)據
- 選擇和過濾數(shù)據
- 創(chuàng)建新列
- 分組和聚合
- 缺失數(shù)據
讀取數(shù)據
在Polars中讀取CSV文件會感覺很熟悉,因為可以像在Pandas中一樣使用.read_csv()方法:
# Pandas
pd.read_csv('example.csv')
# Polars
pl.read_csv('example.csv')
在Pandas和Polars中讀取樣本數(shù)據集的結果執(zhí)行時間如下所示:
Pandas和Polars之間讀取時間的比較
對于我們的樣本數(shù)據集,使用Pandas讀取數(shù)據比使用Polars慢8倍左右。
選擇和過濾數(shù)據
Pandas和Polars之間的第一個主要區(qū)別是Polars不使用索引[1]。相反,每行都以其在DataFrame中的整數(shù)位置為索引[1]。
雖然相同的Pandas代碼也可以在Polars中運行,但這并不是最佳實踐。在Polars中,應該使用.select()方法來選擇數(shù)據。
# Pandas
df[['col1', 'col2']]
# 上述代碼也可以在Polars中運行,
# 但在Polars中的正確方式是:
df.select(pl.col(['col1', 'col2']))
在Pandas和Polars中選擇數(shù)據的執(zhí)行時間結果顯示如下:
Pandas和Polars之間選擇時間的比較
對于我們的樣本數(shù)據集,使用Pandas選擇數(shù)據比使用Polars慢15倍左右(約為70.3微秒)。
下面比較了在文檔中建議的Polars操作語法(使用.select(),左側)和Pandas語法(使用df[['col1','col2']],右側)。令人意外的是,Pandas語法比建議的.select()方法快得多。
圖片
Polars和具有Pandas語法的Polars之間選擇時間的比較(df[[‘col1’,‘col2’]])
在Pandas中,你可以使用.query()方法過濾數(shù)據,但在Polars中需要使用.filter()方法。
# Pandas
df.query('col1 > 5')
# Polars
df.filter(pl.col('col') > 5)
在Pandas和Polars中過濾數(shù)據的執(zhí)行時間結果顯示如下:
Pandas和Polars之間過濾時間的比較
對于我們的樣本數(shù)據集,使用Pandas和Polars過濾數(shù)據的時間大致相同。
與Pandas不同,Polars可以在.select()和.filter()中并行運行操作。
創(chuàng)建新列
在Polars中創(chuàng)建新列也與在Pandas中使用的方式有所不同。在Polars中,需要使用.with_column()或.with_columns()方法,具體取決于你要創(chuàng)建多少列。
# Pandas
df_pd["new_col"] = df_pd["col"] * 10
# Polars
df.with_columns([(pl.col("col") * 10).alias("new_col")])
# 多列的Polars
# df.with_columns([(pl.col("col") * 10).alias("new_col"), ...])
在Pandas和Polars中創(chuàng)建一個新列的結果執(zhí)行時間如下:
Pandas和Polars之間創(chuàng)建新列的時間比較
對于我們的樣本數(shù)據集,在Polars中創(chuàng)建新列需要比Pandas長兩倍左右的時間。
分組和聚合
在Pandas和Polars中,分組和聚合在語法上略有不同,但兩者都使用.groupby()和.agg()方法。
# Pandas
df_pd.groupby('col1')['col2'].agg('mean')
# Polars
# df.groupby('col1').agg([pl.col('col2').mean()]) # 建議使用的Polars方法
df.groupby('col1').agg([pl.mean('col2')]) # 簡短的語法
在Pandas和Polars中對數(shù)據進行分組和聚合的執(zhí)行時間如下:
Pandas和Polars之間聚合時間的比較
對于我們的樣本數(shù)據集,使用Pandas聚合數(shù)據需要比使用Polars長兩倍左右的時間。
缺失數(shù)據
Pandas和Polars之間的另一個主要區(qū)別是,Pandas使用NaN值表示缺失值,而Polars使用null[1]。
圖片
Pandas和Polars如何在DataFrames中表示缺失值
因此,應該使用Polars的.fill_null()方法,而不是Pandas中的.fillna()方法。
# Pandas
df['col2'].fillna(-999)
# Polars
# df_pd.with_column(pl.col('col2').fill_null(pl.lit(-999))) # 建議使用的Polars方法
df_pd.with_column(pl.col('col2').fill_null(-999)) # 簡短的語法
總結
那么,Polars是否比Pandas更好?Polars是否會取代Pandas?
Polars相對于Pandas的主要優(yōu)勢是速度。如果你需要在大型數(shù)據集上進行大量數(shù)據處理,那么你肯定應該嘗試Polars。
Polars相對于Pandas的主要優(yōu)勢是速度。
但是,正如本文所示,如果要從Pandas切換到Polars,則需要學習新的Polars語法。此外,你已經看到,對于相同的操作,Polars代碼通常要比Pandas代碼長。并且,Polars并沒有涵蓋Pandas的所有功能,例如用于數(shù)據探索等。
因此,如果你需要使用Pandas提供的所有功能,則可能需要繼續(xù)使用Pandas。
Polars的代碼通常比Pandas的代碼長。
參考文獻
[1] Polars (2023): User Guide (accessed 8. January 2023)
【網址】:https://pola-rs.github.io/polars-book/user-guide/
[2] “Stackoverflow”, “What are the differences between feather and parquet?”. stackoverflow.com.(accessed July 25, 2022)
【網址】:https://stackoverflow.com/questions/48083405/what-are-the-differences-between-feather-and-parquet