在大數據處理領域,性能和效率始終是核心問題。
polars
作為新一代數據處理框架,通過利用Rust語言的底層實現和現代化的並行計算架構,在處理大規模數據集時展現出顯著的性能優勢。根據性能測試文章的數據顯示,在CSV文件讀取操作中,
polars
的處理速度可達
pandas
的20倍。這種性能提升主要得益於其優化的內存管理機制和並行計算能力。
本文將系統地介紹如何從
pandas
遷移到
polars
,重點關注兩個框架之間的語法對應關係和最佳實踐。
📊 適用場景:
- 處理大規模數據集的效率瓶頸
- 需要提升數據處理性能的工程團隊
- 想要學習現代數據處理框架的工程師
- 正在考慮技術棧升級的技術負責人
⚡️ 核心特性:
- 20倍的性能提升潛力
- 更低的內存佔用
- 完善的並行計算支持
- 類 SQL 的聲明式語法
- 智能的查詢優化器
1、環境配置與基礎設置
首先需要通過pip包管理器安裝必要的庫:
# Pandas安裝
pipinstallpandas
# Polars安裝
pipinstallpolars
在Python環境中導入這些庫:
# Pandas導入語句
importpandasaspd
# Polars導入語句
importpolarsaspl
推薦使用這些標準的別名(pd和pl),因為它們在數據科學社區中被廣泛採用,有助於代碼的可讀性和維護性。
2、DataFrame的創建與基礎操作
DataFrame是數據處理中的核心數據結構,代表二維表格數據:
# Pandas中創建DataFrame
df=pd.DataFrame({'a': [1, 1, 1], 'b': [2, 2, 2]})
# Polars中創建DataFrame
df=pl.DataFrame({'a': [1,1, 1], 'b': [2, 2, 2]})
這裏的DataFrame創建展示了兩個框架的基本語法相似性。兩者都支持通過字典構造數據,其中鍵作為列名,值作為列數據。
3、數據導入操作
數據導入是數據分析的第一步,兩個框架都提供了高效的數據讀取接口:
# Pandas讀取CSV
df=pd.read_csv('data.csv')
# Polars讀取CSV
df=pl.read_csv('data.csv')
Polars的CSV讀取實現了多線程並行處理,對於大型文件的讀取性能顯著優於Pandas。此外Polars還會自動推斷最優的數據類型,減少內存使用。
4、數據檢查與探索
數據探索是理解數據集特徵的關鍵步驟:
# Pandas數據探索方法
df.head() # 查看前幾行數據
df.info() # 顯示數據基本信息
df.describe() # 生成描述性統計
# Polars數據探索方法
df.head() # 查看前幾行數據
df.schema # 顯示數據結構信息
df.describe() # 生成描述性統計
Polars的schema屬性提供了更高效的數據類型查看機制,直接顯示每列的數據類型,而不需要像Pandas的info()那樣進行完整的內存統計。
5、列選擇操作
列選擇是數據處理中的基礎操作,兩個框架採用了不同的語法範式:
# Pandas列選擇
df['a'] # 選擇單列
df[['a', 'b']] # 選擇多列
# Polars列選擇
df.select('a') # 選擇單列
df.select(['a', 'b']) # 選擇多列
Polars的select方法提供了更一致的API接口,可以與其他操作方法輕鬆鏈式調用。這種設計有助於構建更清晰的數據處理流程。
6、數據過濾技術
數據過濾是數據分析中的核心操作,用於根據特定條件選擇數據子集:
# Pandas過濾操作
df[df['a'] >2]
# Polars過濾操作
df.filter(pl.col('a') >2)
Polars的過濾語法更加明確,使用
pl.col()
顯式引用列,這種方式不僅提高了代碼的可讀性,還允許在複雜條件下更靈活的列操作。此外Polars的過濾操作在後台使用了向量化計算,提供更高的執行效率。
7、列操作與數據轉換
最基本的列操作是添加新的計算列:
# Pandas添加列
df['c'] =df['a'] +df['b']
# Polars添加列
df=df.with_columns((pl.col('a') +pl.col('b')).alias('c'))
Polars的
with_columns
方法提供了一個聲明式API,使操作更加清晰且可組合。
複雜的條件轉換在數據處理中很常見:
# Pandas條件轉換
df['b'] =df['a'].apply(lambdax: 1ifx=='high'else0ifx=='equal'else-1)
# Polars條件轉換
df=df.with_columns(
pl.when(pl.col('a') =='high')
.then(1)
.when(pl.col('a') =='equal')
.then(0)
.otherwise(-1)
.alias('b')
)
Polars的條件語法更接近SQL風格,提供了更清晰的邏輯流程,並且實現了更好的性能優化。
在實際應用中,經常需要基於某些列的條件來選擇其他列的值:
# Pandas列間條件選擇
df['d'] =df[['a','b','c']].apply(lambdax: x['a'] ifx['c'] >0.5elsex['b'])
# Polars列間條件選擇
df=df.with_columns(
pl.when(pl.col('c') >0.5)
.then('a') # 選擇列a
.otherwise('b') # 選擇列b
.alias('d')
)
8、列重命名操作
列重命名是數據預處理中的常見需求:
# Pandas重命名
df.rename(columns={'a': 'alpha'})
# Polars重命名
df.rename({'a': 'alpha'})
兩個框架的重命名語法相似,但Polars的實現在處理大數據集時更加高效。
9、分組聚合操作
分組操作允許我們對數據進行細粒度的分析:
# Pandas分組求和
df.groupby('a')['b'].sum()
# Polars分組求和
df.group_by('a').agg(pl.col('b').sum())
在實際應用中,常需要同時計算多個統計指標:
# Pandas多指標聚合
df.groupby('a').agg({'b': ['sum', 'mean'], 'c': 'max'})
# Polars多指標聚合
df.group_by('a').agg([
pl.col('b').sum().alias('b_sum'),
pl.col('b').mean().alias('b_mean'),
pl.col('c').max().alias('c_max')
])
Polars的分組聚合語法更加顯式,雖然代碼量稍多,但提供了更好的類型安全性和性能優化空間。每個聚合操作都可以被單獨優化,並且支持並行計算。
分組排名計算
在數據分析中,計算組內排名是一個常見需求:
# Pandas分組排名
df['rank'] =df.groupby('a')['b'].rank(method='dense')
# Polars分組排名
df=df.with_columns(
pl.col('b').rank('dense').over('a').alias('rank')
)
Polars的語法採用了SQL風格的
over
子句,這種設計更接近標準的數據處理範式,並且在處理大規模數據集時更有效率。
分組轉換操作
對分組數據進行轉換是數據處理中的高級操作:
# Pandas分組轉換
df['sum_squared'] =df.groupby('a')['b'].transform(lambdax: x.sum() *2)
# Polars分組轉換
df=df.with_columns(
(pl.col('b').sum().over('a') *2).alias('sum_squared')
)
Polars的實現避免了使用lambda函數,提供了更直接的列操作方式,這不僅提高了代碼的可讀性,還實現了更好的性能優化。
10、時間窗口計算
滑動窗口計算在時間序列分析中極為重要:
# Pandas滑動平均
df['rolling_avg'] =df['b'].rolling(window=3).mean()
# Polars滑動平均
df=df.with_columns(
pl.col('b').rolling_mean(window_size=3).alias('rolling_avg')
)
Polars的窗口操作實現了更高效的內存管理,特別適合處理大規模時間序列數據。
11、累計統計計算
累計統計在數據分析中用於追蹤數據的演變趨勢:
# Pandas累計統計
df['cum_sum'] =df['b'].cumsum()
df['cum_prod'] =df['b'].cumprod()
df['cum_mean'] =df['b'].expanding().mean()
# Polars累計統計
df.with_columns([
pl.col('b').cum_sum().alias('cum_sum'),
pl.col('b').cum_prod().alias('cum_prod'),
pl.col('b').cumulative_eval(pl.element().mean()).alias('cum_mean')
])
Polars提供了更統一的累計計算接口,並且支持更復雜的自定義累計操作。
12、條件聚合操作
條件聚合允許我們基於特定條件計算統計量:
# Pandas條件聚合
df['sum_if'] =df[df['a'] >2]['b'].sum()
# Polars條件聚合
sum_if=df.filter(pl.col('a') >2).select(pl.col('b').sum()).item()
Polars的實現更加直觀,並且通過優化的查詢計劃提供更好的性能。
13、 排序操作
數據排序是數據分析中的基礎操作:
# Pandas排序
df.sort_values(by='a')
# Polars排序
df.sort('a')
Polars提供了更簡潔的排序語法,同時在底層實現了更高效的排序算法。
14、空值處理
處理缺失數據是數據清洗的重要環節:
# Pandas空值處理
df.fillna(0) # 填充空值
df.dropna() # 刪除包含空值的行
# Polars空值處理
df.fill_null(0) # 填充空值
df.drop_nulls() # 刪除包含空值的行
Polars對空值的處理採用了更現代的命名方式,並且在實現上考慮了內存效率和計算性能。
15、DataFrame連接操作
數據集的連接操作是數據整合的核心技術:
# Pandas數據連接
df_merged=pd.merge(df1, df2, on='key', how='inner')
# Polars數據連接
df_merged=df1.join(df2, on='key', how='inner')
Polars的連接操作採用了更接近SQL的語法,並且在實現上使用了哈希連接和排序合併連接等優化技術,顯著提升了大數據集的連接性能。支持的連接類型包括:
- inner:內連接,僅保留匹配的記錄
- left:左連接,保留左表所有記錄
- outer:外連接,保留所有記錄
- cross:交叉連接,生成笛卡爾積
16、數據集合並
數據集合並用於處理來自不同源的數據:
# Pandas數據合併
df_concat_vert=pd.concat([df1, df2], axis=0) # 垂直合併
df_concat_horiz=pd.concat([df1, df2], axis=1) # 水平合併
# Polars數據合併
df_concat_vert=pl.concat([df1, df2]) # 垂直合併
df_concat_horiz=pl.concat([df1, df2], how='horizontal') # 水平合併
Polars的合併操作在處理大規模數據集時表現出更好的內存效率,並且提供了更直觀的參數設置。垂直合併特別適用於處理分片數據或時間序列數據的合併。
17、數據透視表操作
數據透視表是數據分析中的重要工具,用於多維度數據彙總:
# Pandas數據透視表
df.pivot_table(index='a', columns='b', values='c', aggfunc='sum')
# Polars數據透視表
df.pivot(values='c', index='a', columns='b', aggregate_fn='sum')
更復雜的場景下,可能需要同時計算多個聚合指標:
# Pandas多重聚合透視表
df.pivot_table(index='a', columns='b', values='c', aggfunc=['sum', 'mean'])
# Polars多重聚合透視表
df.group_by(['a', 'b']).agg([
pl.col('c').sum().alias('c_sum'),
pl.col('c').mean().alias('c_mean')
]).pivot(values=['c_sum', 'c_mean'], index='a', columns='b')
Polars的實現雖然寫法較長,但提供了更靈活的聚合函數定義能力,並且在處理大規模數據集時性能更優。
18、列表類型數據展開
處理嵌套數據結構是數據預處理中的常見需求:
# Pandas列表展開
df=pd.DataFrame({'a': [1, 2], 'b': [[1, 2], [3, 4]]})
df=df.explode('b')
# Polars列表展開
df=pl.DataFrame({'a': [1, 2], 'b': [[1, 2], [3, 4]]})
df=df.explode('b')
兩個框架在這方面的語法非常相似,但Polars的實現在內存使用上更加高效,特別是在處理大型嵌套數據結構時。
19、數據導出
數據處理完成後的導出操作:
# Pandas導出CSV
df.to_csv('output.csv', index=False)
# Polars導出CSV
df.write_csv('output.csv')
Polars提供了多線程寫入能力,可以顯著提升大數據集的導出速度。
20、惰性求值
Polars的一個重要特性是支持惰性求值:
- 使用
lazy()方法將DataFrame轉換為LazyFrame - 可以構建複雜的查詢計劃而不立即執行
- 通過
collect()觸發實際計算 - 能夠自動優化查詢計劃,提升性能
示例:
# 惰性操作鏈
result= (df.lazy()
.filter(pl.col('value') >0)
.group_by('category')
.agg(pl.col('value').sum())
.collect())
總結
Polars作為現代化的數據處理框架,通過先進的工程實踐和算法優化,為數據科學工作者提供了高效的數據處理工具。在從Pandas遷移時,理解這些核心概念和最佳實踐將有助於充分發揮Polars的性能優勢。
https://avoid.overfit.cn/post/c9ffc87af55f4cd494d7954c11ce384c