Python NumPy 2.0 完整升級指南:Copy-on-Write、StringDType 與效能大躍進
身為一個寫了五年 pandas 的 Python 開發者,我一直覺得 pandas 就是資料處理的終極答案。直到有一天,我的同事丟了一個 2GB 的 CSV 給我,pandas 讀了整整 45 秒,而他用 Polars 只花了 3 秒。那一刻,我的世界觀徹底改變了。
今天就來跟大家分享我從 pandas 轉向 Polars 的心路歷程,以及為什麼你也應該認識這個強大的 Python Polars DataFrame 替代方案。
什麼是 Polars?
Polars 是一個用 Rust 語言編寫的高效能 DataFrame 函式庫,專為 Python 和 Rust 設計。它的核心概念跟 pandas 很像——都是用來處理表格式資料——但底層架構完全不同。
如果你熟悉 Pandas 資料分析入門,那學 Polars 會非常順手,因為很多概念是相通的,只是語法稍有差異。
為什麼 Polars 比 Pandas 快這麼多?
Polars 之所以能碾壓 pandas 的效能,主要靠三大技術:
1. Rust 底層引擎
pandas 底層是用 C 和 Cython 寫的,而 Polars 用的是 Rust。Rust 提供了零成本抽象和記憶體安全,不需要垃圾回收機制,天生就比較快。
2. Apache Arrow 記憶體格式
Polars 使用 Apache Arrow 作為記憶體中的資料格式。Arrow 是列式儲存(columnar format),對於分析型查詢特別有效率。相比 pandas 使用的 NumPy 陣列,Arrow 在記憶體使用和快取命中率上都更優秀。
3. 惰性求值(Lazy Evaluation)
這是 Polars 最厲害的殺手鐧。pandas 的每一步操作都會立刻執行,而 Polars 的 lazy 模式會先把所有操作記錄下來,最後一次性優化並執行。就像是先寫好完整的 SQL 查詢計畫,再一次送出去跑。
安裝 Polars
安裝非常簡單,推薦使用 uv 套件管理器 來安裝:
# 使用 pip
pip install polars
# 使用 uv(推薦,速度更快)
uv pip install polars
# 如果需要額外功能(讀取 Excel、連接資料庫等)
pip install polars[all]建議在 Python 虛擬環境 中安裝,避免套件衝突。
基本操作:Pandas vs Polars 語法對照
接下來用實際的程式碼來比較兩者的語法差異。這是學 Python Polars DataFrame 最直覺的方式。
讀取 CSV 檔案
# Pandas
import pandas as pd
df_pd = pd.read_csv("sales.csv")
# Polars
import polars as pl
df_pl = pl.read_csv("sales.csv")語法幾乎一模一樣!但 Polars 在讀取大檔案時,速度可以快 5-10 倍。
篩選資料(Filter)
# Pandas
result_pd = df_pd[df_pd["amount"] > 1000]
# Polars
result_pl = df_pl.filter(pl.col("amount") > 1000)Polars 使用 pl.col() 來指定欄位,語法更明確、更不容易出錯。
分組聚合(GroupBy)
# Pandas
result_pd = df_pd.groupby("category")["amount"].agg(["sum", "mean"])
# Polars
result_pl = df_pl.group_by("category").agg(
pl.col("amount").sum().alias("total"),
pl.col("amount").mean().alias("average")
)Polars 的 group_by 語法更直觀,每個聚合操作都可以用 .alias() 自訂欄位名稱,不用事後再改。
合併資料(Join)
# Pandas
result_pd = pd.merge(orders, customers, on="customer_id", how="left")
# Polars
result_pl = orders.join(customers, on="customer_id", how="left")新增計算欄位
# Pandas
df_pd["profit_rate"] = df_pd["profit"] / df_pd["revenue"]
# Polars
df_pl = df_pl.with_columns(
(pl.col("profit") / pl.col("revenue")).alias("profit_rate")
)Lazy 模式:Polars 的真正威力
前面的範例都是 eager 模式(立即執行),但 Polars 真正厲害的是 lazy 模式:
# Lazy 模式:先規劃,最後一次執行
result = (
pl.scan_csv("huge_file.csv") # 不會立刻讀取整個檔案
.filter(pl.col("year") >= 2024)
.group_by("department")
.agg(
pl.col("salary").mean().alias("avg_salary"),
pl.col("employee_id").count().alias("headcount")
)
.sort("avg_salary", descending=True)
.collect() # 這一步才真正執行所有操作
)在 .collect() 之前,Polars 會自動優化查詢計畫:合併不必要的步驟、只讀取需要的欄位(projection pushdown)、提前篩選資料(predicate pushdown)。處理大型資料集時,這些優化可以帶來數倍甚至數十倍的加速。
什麼時候該用 Polars?什麼時候繼續用 Pandas?
選 Polars 的時機
- 資料量大:超過 100MB 的 CSV 或百萬筆以上的資料
- 效能瓶頸:pandas 跑太慢,需要加速
- 記憶體不足:Polars 的記憶體效率更好
- ETL Pipeline:批次資料處理、定期報表生成
- 新專案:沒有歷史包袱,直接用 Polars 開始
繼續用 Pandas 的時機
- 生態系整合:搭配 scikit-learn、statsmodels 等需要 pandas 的套件
- 既有程式碼:大量現有的 pandas 程式碼不值得重寫
- 小型資料:幾千筆資料兩者差異不大
- Jupyter 探索:pandas 在互動式分析的顯示支援更成熟
好消息是,Polars 可以輕鬆跟 pandas 互轉:
# Polars → Pandas
pandas_df = polars_df.to_pandas()
# Pandas → Polars
polars_df = pl.from_pandas(pandas_df)從 Pandas 遷移到 Polars 的實用建議
如果你決定開始使用 Polars,這裡有幾個過來人的建議:
- 先學 Expression API:
pl.col()、.alias()、.over()是 Polars 的核心語法,熟悉後會覺得比 pandas 更直覺。 - 優先使用 Lazy 模式:用
scan_csv()取代read_csv(),讓 Polars 幫你優化查詢。 - 不要用 apply():Polars 的 Expression API 能覆蓋大部分需求,避免使用
.apply()才能享受到效能優勢。 - 漸進式遷移:不必一次全改,可以在效能瓶頸的地方先導入 Polars,再逐步擴大範圍。
- 善用
.to_pandas():遷移過渡期間,把 Polars 的結果轉成 pandas 餵給下游還在用 pandas 的程式碼。
處理完資料之後,你可能會需要用 Matplotlib 視覺化 來呈現分析結果。Polars DataFrame 可以輕鬆轉成 pandas 再傳給 Matplotlib 繪圖。
結語
Polars 不是要取代 pandas,而是提供了一個更現代、更快速的選擇。在資料量越來越大的今天,學會 Polars 絕對是值得的投資。
我自己的工作流程是:小型探索用 pandas,正式的資料管線用 Polars。兩者並存,各取所長。
如果你還在猶豫,建議就先拿一個現有的 pandas 腳本,用 Polars 重寫看看。當你看到速度差異的那一刻,你就會跟我一樣回不去了。
繼續閱讀
Python Matplotlib 資料視覺化入門教學:用圖表說故事的完整指南
資料分析做完了,但老闆看不懂你的數字?Matplotlib 是 Python 最經典的繪圖套件,這篇教你從零畫出各種圖表,讓數據自己說話。
相關文章
你可能也喜歡
探索其他領域的精選好文