在处理大规模数据时,Pandas 常常面临内存不足、运行缓慢的问题。Polars 是一个基于 Rust 的高性能 DataFrame 库,能够在保持类似 API 的同时,将处理速度提升 10 到 100 倍。Polars 2.0 已发布首个候选版本,正式版预计在未来几周内推出。本文将带你从零开始掌握 Polars 的核心用法,并给出从 Pandas 迁移的实用步骤。
为什么选择 Polars
- 速度:Polars 比 Pandas 快 5–10 倍(典型任务),部分基准测试中可达 10–100 倍。
- 内存效率:采用 Apache Arrow 列式存储,支持惰性求值与流式处理,内存占用更低。
- 开源:MIT 许可证,社区活跃,截至公司公告已超过 600 万次下载、19 000+ GitHub 星标。
- 并行化:原生多线程与 SIMD 优化,无需额外配置即可利用多核。
安装与版本
bash pip install polars
导入习惯:
python import polars as pl print(pl.version) # 例如 1.44.2
快速上手
创建 DataFrame
python df = pl.DataFrame({ 'name': ['Alice', 'Bob', 'Charlie'], 'age': [25, 30, 35], 'salary': [8200, 9500, 12000], })
读取 CSV
python df = pl.read_csv('employees.csv')
基本操作
python
选择列
df.select('name', 'salary')
筛选
df.filter(pl.col('age') > 25)
新增列
df.with_columns((pl.col('salary') / 1000).alias('salary_k'))
排序
df.sort('salary', descending=True)
分组聚合
df.group_by('dept').agg( pl.col('salary').mean().alias('avg_salary'), pl.len().alias('count'), )
惰性求值:提升性能的关键
对于大文件,建议使用 scan_csv 代替 read_csv,它只构建查询计划,不立即加载数据。
python
惰性读取
lazy_df = pl.scan_csv('large_data.csv')
构建查询
result = ( lazy_df .filter(pl.col('amount') > 1000) .select('user_id', 'amount') .group_by('user_id') .agg(pl.col('amount').sum().alias('total')) .sort('total', descending=True) .head(100) .collect() # 真正执行 )
Polars 的查询优化器会自动进行谓词下推、投影下推等优化,只读取必要的数据。
从 Pandas 迁移
| Pandas | Polars |
|---|---|
pd.read_csv() | pl.read_csv() |
df.head() | df.head() |
df[df['age'] > 25] | df.filter(pl.col('age') > 25) |
df.groupby('x').mean() | df.group_by('x').agg(pl.col('mean')) |
| 无惰性求值 | df.lazy().collect() |
互转:
python
Pandas → Polars
pl_df = pl.from_pandas(pd_df)
Polars → Pandas
pd_df = pl_df.to_pandas()
重要特性
- 不可变性:所有操作返回新 DataFrame,不存在
inplace=True的困惑。 - 严格类型:
null与NaN区分,不会隐式将整数转为浮点数。 - Copy‑on‑Write:克隆几乎零开销。
- 嵌套 List:原生支持,Pandas 需借助 object dtype。
注意事项
- 行序不保证:在 Polars 2.0 中,流式引擎默认不保证
join、group_by等操作的行序。如需保持顺序,设置maintain_order=True。 - 严格类型转换:2.0 版本移除了许多隐式转换,例如
is_in中的类型不匹配会抛出错误,需显式转换。 - 引擎 affinity:可通过
pl.Config.set_engine_affinity('in-memory')回退到旧引擎。
下一步行动
- 尝试将现有 Pandas 脚本中的
read_csv替换为scan_csv,体验惰性求值。 - 对需要保持顺序的操作添加
maintain_order=True。 - 查阅官方迁移指南:https://pola.rs/posts/announcing-polars-2/
- 使用
pl.Config.set_engine_affinity根据需求切换引擎。
通过以上步骤,你可以在不改变太多代码的前提下,获得显著的性能提升。Polars 的设计哲学是"又快又干净",非常适合处理大规模数据集。