
本文详解如何在 polars 中通过 `.pivot()` 方法完成基于列值的宽表转换(即“unstack”),替代 pandas 的 `groupby().sum().unstack()` 模式,并处理缺失值填充等关键细节。
在数据处理中,将长格式(long format)DataFrame 转换为宽格式(wide format)是常见需求,例如按某一列(如 left)分组,再将另一列(如 center)的唯一值作为新列名,对目标数值列(如 right)进行聚合(如求和)。Pandas 中惯用 groupby().sum().unstack(fill_value=0) 实现;而在 Polars 中,对应的核心方法是 .pivot() —— 它专为这类结构化透视设计,性能更优、语义更清晰。
以下为完整实现步骤:
1. 构造示例数据
import polars as pl
df = pl.DataFrame({
"left": ["One", "One", "One", "One", "Two"],
"center": ["P", "P", "I", "I", "I"],
"right": [100, 100, 100, 100, 100]
})2. 使用 .pivot() 进行透视聚合
调用 df.pivot() 时需明确三个关键参数:
- values:待聚合的数值列(此处为 "right");
- index:作为新表行索引的列(此处为 "left");
- columns:用于生成新列名的列(此处为 "center");
- aggregate_function:指定聚合逻辑,支持字符串(如 "sum")或表达式(如 pl.col("right").sum())。
✅ 推荐写法(清晰且显式):
result = df.pivot(
values="right",
index="left",
columns="center",
aggregate_function="sum"
)⚠️ 注意:原始答案中 df.pivot('center', index='left', ...) 的参数顺序已过时(旧版 Polars API),当前稳定版(v0.20+)必须显式使用关键字参数 values, index, columns,否则会报错或行为异常。
执行后输出为:
shape: (2, 3) ┌──────┬─────┬─────┐ │ left ┆ P ┆ I │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞══════╪═════╪═════╡ │ One ┆ 200 ┆ 200 │ │ Two ┆ null ┆ 100 │ └──────┴─────┴─────┘
3. 处理缺失值:fill_null(0)
与 Pandas 的 fill_value=0 类似,Polars 中需链式调用 .fill_null(0):
result = (
df.pivot(
values="right",
index="left",
columns="center",
aggregate_function="sum"
)
.fill_null(0)
)最终结果完全匹配预期:
shape: (2, 3) ┌──────┬─────┬─────┐ │ left ┆ P ┆ I │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞══════╪═════╪═════╡ │ One ┆ 200 ┆ 200 │ │ Two ┆ 0 ┆ 100 │ └──────┴─────┴─────┘
✅ 关键注意事项
- 参数命名强制化:新版 Polars 不再支持位置传参,values/index/columns 必须以关键字形式传入;
- 聚合函数灵活性:除 "sum" 外,还支持 "mean"、"count"、"first" 等字符串简写,或自定义表达式(如 pl.col("right").max().over("left"));
- 多值透视:若需同时透视多个数值列,可传入列表:values=["right", "other_col"];
- 性能优势:.pivot() 是 Polars 原生优化操作,相比手动 group_by().agg() + join() 组合,内存效率与执行速度更佳。
掌握 .pivot() 是构建高效 Polars 数据流水线的重要一环——它不仅是语法替代,更是向声明式、向量化思维的自然演进。










