如何在Polars中按组计算所有前置条目的平均值?
解决方案
可以通过分组窗口函数结合累计求和、累计计数来实现需求,代码如下:
import polars as pl df = pl.from_repr(""" ┌──────┬────────┐ │ Name ┆ Number │ │ --- ┆ --- │ │ str ┆ i64 │ ╞══════╪════════╡ │ Mr.A ┆ 1 │ │ Mr.A ┆ 4 │ │ Mr.A ┆ 5 │ │ Mr.B ┆ 3 │ │ Mr.B ┆ 5 │ │ Mr.B ┆ 6 │ │ Mr.B ┆ 10 │ └──────┴────────┘ """) result = df.with_columns( pl.when(pl.col("Number").cumcount().over("Name") == 0) .then(pl.lit(0.0)) .otherwise( pl.col("Number").cumsum().over("Name").shift(1) / pl.col("Number").cumcount().over("Name") ) .alias("average") ) print(result)
逻辑说明:
- 分组累计计数:
pl.col("Number").cumcount().over("Name")会在每个Name组内生成从0开始的序号,用来判断是否是组内第一条数据(序号为0时设为0.0)。 - 前置值累计求和:
pl.col("Number").cumsum().over("Name").shift(1)计算组内到当前行之前的所有Number值的总和——cumsum()生成累计和,shift(1)把结果往后挪一行,刚好对应当前行之前的总和。 - 计算平均值:用前置总和除以累计计数(也就是前面的条目数量),得到要求的平均值。
为什么不用rolling_mean?
rolling_mean的窗口大小是固定的,只能计算固定窗口内的平均值,无法实现"当前行之前所有同组数据"的动态累计计算,而且默认会包含当前行,不符合需求。
内容的提问来源于stack exchange,提问作者user24758287
相关产品推荐
相关产品推荐

