You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Polars中计算分组求和并保留所有原始行

如何在Polars中计算分组求和并保留所有原始行

嘿,我太懂这种对着简单问题卡壳的感觉了!你一开始用的group_by().agg()其实是做聚合压缩——它会把每个分组合并成一行,但你要的是保留所有原始行,同时给每行添加上对应分组的求和结果,这时候用窗口函数就对了!

举个具体的例子,就用你给出的数据集:

import polars as pl

df = pl.DataFrame(
    {
        "a": ["a", "b", "a", "b", "c"],
        "b": [1, 2, 1, 3, 3],
    }
)

如果你用传统的group_by().agg(),得到的是每个分组压缩后的结果:

df.group_by("a").agg(pl.col("b").sum())
# 输出:
# shape: (3, 2)
# ┌─────┬─────┐
# │ a   ┆ b   │
# │ --- ┆ --- │
# │ str ┆ i64 │
# ╞═════╪═════╡
# │ a   ┆ 2   │
# │ b   ┆ 5   │
# │ c   ┆ 3   │
# └─────┴─────┘

但你要的是保留原始的5行,每行都带上对应分组的总和,这时候用over()指定窗口分区就行:

# 新增分组求和列,保留所有原始行
result_df = df.with_columns(
    group_sum_b=pl.col("b").sum().over("a")
)

print(result_df)

运行后会得到你想要的结果:

shape: (5, 3)
┌─────┬─────┬───────────┐
│ a   ┆ b   ┆ group_sum_b │
│ --- ┆ --- ┆ ---       │
│ str ┆ i64 ┆ i64       │
╞═════╪═════╪═══════════╡
│ a   ┆ 1   ┆ 2         │
│ b   ┆ 2   ┆ 5         │
│ a   ┆ 1   ┆ 2         │
│ b   ┆ 3   ┆ 5         │
│ c   ┆ 3   ┆ 3         │
└─────┴─────┴───────────┘

简单解释下:

  • pl.col("b").sum()是计算求和,但加上.over("a")后,它会按"a"列的分组分别计算求和
  • 这个求和结果会被自动广播到该分组的每一行,所以原始的所有行都保留了,同时每行都能看到自己所在分组的总和

如果需要按多列分组计算,也很简单,把over()里的参数改成列表就行,比如over(["a", "another_column"])

备注:内容来源于stack exchange,提问作者gernophil

火山引擎 最新活动