Polars中用.rolling与.agg保留原始列(无需join或.over)
在Polars中滚动聚合保留原始列的方案
要实现**不关联原始列、不用.over、保留原始单个值列、支持group_by**的滚动聚合,核心思路是:分离滚动聚合计算与原始列保留——先单独计算滚动聚合指标,再将结果与原始DataFrame通过分组键+时间列(或唯一标识)关联。
具体步骤
- 单独计算滚动聚合结果:仅在
.agg()中定义需要的聚合指标(如求和、均值),不要包含原始列(避免变成窗口列表)。 - 关联原始数据:将聚合结果与原始DataFrame通过唯一标识(分组键+时间列)进行左连接,即可保留所有原始列,同时新增聚合结果列。
示例代码
带分组的场景
import polars as pl dates = [ "2020-01-01 13:45:48", "2020-01-01 16:42:13", "2020-01-01 16:45:09", "2020-01-02 18:12:48", "2020-01-03 19:45:32", "2020-01-08 23:16:43", ] # 构造带分组的示例数据 df = pl.DataFrame({ "group": ["X", "X", "Y", "Y", "X", "Y"], "dt": dates, "a": [3, 7, 5, 9, 2, 1] }).with_columns( pl.col("dt").str.to_datetime().set_sorted() ) # 步骤1:计算7天滚动求和(仅生成聚合列) rolling_agg = df.group_by("group").rolling( index_column="dt", period="7d" # 滚动窗口周期 ).agg( pl.col("a").sum().alias("rolling_sum_7d"), pl.col("a").mean().alias("rolling_mean_7d") # 可添加多个聚合指标 ) # 步骤2:关联原始数据,保留所有原始列 result = df.join(rolling_agg, on=["group", "dt"], how="left") print(result)
无分组的场景
如果不需要分组,直接去掉group_by即可:
# 无分组的滚动聚合计算 rolling_agg = df.rolling(index_column="dt", period="7d").agg( pl.col("a").sum().alias("rolling_sum_7d") ) # 关联原始数据 result = df.join(rolling_agg, on="dt", how="left")
方案优势
- 滚动聚合结果的行数与原始DataFrame完全一致,每个行对应自身窗口的聚合结果,通过
group+dt(或仅dt)可以精准匹配。 - 完全避开了
.over语法,同时不需要用last()/first()模拟原始列,直接保留了原始数据的所有字段。
内容的提问来源于stack exchange,提问作者Olivier_s_j
相关产品推荐
相关产品推荐

