概述
Polars 是一个基于 Apache Arrow 构建的快速 DataFrame 库,面向 Python 与 Rust。它围绕表达式 API、惰性求值框架和高性能数据操作能力设计,可用于高效数据处理、pandas 迁移和数据管道优化。
安装
uv pip install polars
核心概念
表达式
表达式是 Polars 操作的基本构建块,描述对数据的转换,可组合、复用并被优化。
- 使用
pl.col("column_name")引用列 - 链式调用方法构建复杂转换
- 表达式是惰性的,只在 select、with_columns、filter、group_by 等上下文中执行
示例:
df.select(
pl.col("name"),
(pl.col("age") * 12).alias("age_in_months")
)
惰性与即时求值
即时(DataFrame):操作立即执行。
df = pl.read_csv("file.csv")
result = df.filter(pl.col("age") > 25)
惰性(LazyFrame):操作先构建查询计划,优化后再执行。
lf = pl.scan_csv("file.csv")
result = lf.filter(pl.col("age") > 25).select("name", "age")
df = result.collect()
适合使用惰性的情况:处理大数据集、复杂查询管道、只需要部分行列、对性能要求较高。惰性求值的优势包括自动查询优化、谓词下推、投影下推和并行执行。
常用操作
选择
df.select("name", "age")
df.select(
pl.col("name"),
(pl.col("age") * 2).alias("double_age")
)
df.select(pl.col("^.*_id$"))
筛选
df.filter(pl.col("age") > 25)
df.filter(
pl.col("age") > 25,
pl.col("city") == "NY"
)
df.filter(
(pl.col("age") > 25) | (pl.col("city") == "LA")
)
添加或修改列
df.with_columns(
age_plus_10=pl.col("age") + 10,
name_upper=pl.col("name").str.to_uppercase()
)
df.with_columns(
pl.col("value") * 10,
pl.col("value") * 100,
)
分组与聚合
df.group_by("city").agg(
pl.col("age").mean().alias("avg_age"),
pl.len().alias("count")
)
df.group_by("city", "department").agg(
pl.col("salary").sum()
)
df.group_by("city").agg(
(pl.col("age") > 30).sum().alias("over_30")
)
聚合与窗口函数
group_by 上下文中常用聚合:pl.len() 计数、pl.col("x").sum() 求和、pl.col("x").mean() 求平均、pl.col("x").min() / max() 求极值、pl.first() / pl.last() 取首末值。
使用 over() 的窗口函数可在保留行数的同时应用聚合:
df.with_columns(
avg_age_by_city=pl.col("age").mean().over("city"),
rank_in_city=pl.col("salary").rank().over("city")
)
df.with_columns(
group_avg=pl.col("value").mean().over("category", "region")
)
映射策略:group_to_rows(默认,保留原始行顺序)、explode(更快但将分组行聚在一起)、join(生成列表列)。
数据 I/O
支持读取与写入 CSV、Parquet、JSON、Excel,可通过连接器访问数据库,支持云存储(S3、Azure、GCS)和 Google BigQuery,以及多文件/分区文件。
df = pl.read_csv("file.csv")
df.write_csv("output.csv")
lf = pl.scan_csv("file.csv")
result = lf.filter(...).select(...).collect()
df = pl.read_parquet("file.parquet")
df.write_parquet("output.parquet")
df = pl.read_json("file.json")
df.write_json("output.json")
Parquet 在性能上更受推荐。
转换操作
连接
df1.join(df2, on="id", how="inner")
df1.join(df2, on="id", how="left")
df1.join(df2, left_on="user_id", right_on="id")
拼接
pl.concat([df1, df2], how="vertical")
pl.concat([df1, df2], how="horizontal")
pl.concat([df1, df2], how="diagonal")
透视与逆透视
df.pivot(values="sales", index="date", columns="product")
df.unpivot(index="id", on=["col1", "col2"])
pandas 迁移
Polars 相比 pandas 有显著性能提升,API 更清晰。主要概念差异:
- 无索引:Polars 仅使用整数位置
- 严格类型:不做隐式类型转换
- 惰性求值:通过 LazyFrame 提供
- 默认并行:操作自动并行化
常用操作对照:
| 操作 | Pandas | Polars |
|---|---|---|
| 选择列 | df["col"] |
df.select("col") |
| 筛选 | df[df["col"] > 10] |
df.filter(pl.col("col") > 10) |
| 添加列 | df.assign(x=...) |
df.with_columns(x=...) |
| 分组 | df.groupby("col").agg(...) |
df.group_by("col").agg(...) |
| 窗口 | df.groupby("col").transform(...) |
df.with_columns(...).over("col") |
语法模式对比:
# Pandas 顺序执行
df.assign(
col_a=lambda df_: df_.value * 10,
col_b=lambda df_: df_.value * 100
)
# Polars 并行执行
df.with_columns(
col_a=pl.col("value") * 10,
col_b=pl.col("value") * 100,
)
最佳实践
性能优化
- 大数据集使用惰性求值:
lf = pl.scan_csv("large.csv"),而非read_csv - 避免在热点路径中使用 Python 函数,尽量停留在表达式 API 内以利用并行化,仅在必要时使用
.map_elements(),优先使用 Polars 原生操作 - 超大数据使用流式处理:
lf.collect(streaming=True) - 尽早只选择需要的列:
lf.select("col1", "col2").filter(...)优于先在全列上筛选 - 使用合适的数据类型:低基数字符串用 Categorical,选择合适的整数宽度(i32 与 i64),时间数据使用日期类型
表达式模式
pl.when(condition).then(value).otherwise(other_value)
df.select(pl.col("^.*_value$") * 2)
pl.col("x").fill_null(0)
pl.col("x").is_null()
pl.col("x").drop_nulls()
参考资料
该技能包含综合参考文档:
references/core_concepts.md- 表达式、惰性求值和类型系统的详细说明references/operations.md- 所有常用操作的综合指南与示例references/pandas_migration.md- 从 pandas 迁移到 Polars 的完整指南references/io_guide.md- 所有支持格式的数据 I/O 操作references/transformations.md- 连接、拼接、透视与重塑操作references/best_practices.md- 性能优化技巧与常见模式
当用户需要特定主题的详细信息时,可按需加载这些参考文档。
限制
关于收费、价格、平台支持范围、性能基准数据等具体信息,资料中暂未提供。