Polars中如何用单个表达式实现二阶聚合操作?
Polars单表达式实现嵌套分组聚合需求
原始DataFrame
import polars as pl df = pl.DataFrame({'a':[1,1,1,1,2,2,2,2],'b':[1,2,1,2,1,2,1,2],'c':[10,11,12,13,14,15,18,17]}) print(df)
输出:
shape: (8, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ 1 ┆ 1 ┆ 10 │ │ 1 ┆ 2 ┆ 11 │ │ 1 ┆ 1 ┆ 12 │ │ 1 ┆ 2 ┆ 13 │ │ 2 ┆ 1 ┆ 14 │ │ 2 ┆ 2 ┆ 15 │ │ 2 ┆ 1 ┆ 18 │ │ 2 ┆ 2 ┆ 17 │ └─────┴─────┴─────┘
需求说明
按列a分组后,每个组内再按列b进行二级分组,取每个二级分组的最后一个c值,再求这些值的最大值。
当前两步实现代码
df.with_columns(pl.col("c").last().over(["a", "b"])).group_by(pl.col("a")).agg(pl.col("c").max())
输出:
shape: (2, 2) ┌─────┬─────┐ │ a ┆ c │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 2 ┆ 18 │ │ 1 ┆ 13 │ └─────┴─────┘
单表达式实现方案
可以利用Polars的嵌套表达式能力,直接在group_by.agg中完成所有计算,无需额外的with_columns步骤:
写法1(简洁版)
df.group_by("a").agg( pl.col("c").last().over("b").max() )
写法2(明确分组范围版)
如果需要更清晰地指定二级分组的范围(确保b的分组是在a的组内生效),可以显式写出完整的窗口分组键:
df.group_by("a").agg( pl.col("c").last().over(["a", "b"]).max() )
两种写法都能得到和两步法完全一致的结果,核心是将原本在with_columns中计算的窗口逻辑直接嵌入到聚合操作里,利用Polars对嵌套表达式的支持完成一次计算。
内容的提问来源于stack exchange,提问作者figs_and_nuts
相关产品推荐
相关产品推荐

