You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Polars中链式.over()调用rolling_mean结果异常,sum无此问题

Polars中链式.over()调用下rolling_mean与sum的行为差异及解决方案

问题原因

这是Polars当前表达式执行逻辑的已知限制,并非bug。核心差异源于两类函数的计算特性:

  • 聚合类函数(如sum):sum().over('grp')会为每个grp分组生成常量值,后续.over('date')仅对这些常量值按date分组排名,不会改变之前的聚合结果,因此单表达式与分步执行结果一致。
  • 滚动类函数(如rolling_mean):rolling_mean(2).over('grp')需要在grp分组内按行顺序计算窗口均值,但当链式调用第二个.over('date')时,Polars会重置计算上下文,将滚动窗口的分组逻辑替换为date,导致原grp分组的滚动计算失效,最终返回全null。

不使用临时列的解决方案

通过子表达式嵌套的方式,强制先完成grp分组的滚动计算,再对结果执行date分组的排名,避免上下文被覆盖:

pldf = pl.DataFrame({'grp': ['a', 'a', 'b', 'b'], 'date':[1,2,1,2], 'val': [0.5] * 4})
# 正确的单表达式写法
expr_fixed = pl.col(pl.col('val').rolling_mean(2).over('grp')).rank().over('date')
pldf.with_columns(expr_fixed.alias('rank'))

执行后会得到与分步执行一致的正确结果:

shape: (4, 4)
┌─────┬──────┬─────┬──────┐
│ grp ┆ date ┆ val ┆ rank │
│ --- ┆ ---  ┆ --- ┆ ---  │
│ str ┆ i64  ┆ f64 ┆ f64  │
╞═════╪══════╪═════╪══════╡
│ a   ┆ 1    ┆ 0.5 ┆ 1.5  │
│ a   ┆ 2    ┆ 0.5 ┆ 1.5  │
│ b   ┆ 1    ┆ 0.5 ┆ 1.5  │
│ b   ┆ 2    ┆ 0.5 ┆ 1.5  │
└─────┴──────┴─────┴──────┘

补充说明

另一种等价写法是用pl.select()包裹滚动计算步骤,同样能强制计算顺序:

expr_fixed = pl.select(pl.col('val').rolling_mean(2).over('grp')).rank().over('date')

内容的提问来源于stack exchange,提问作者noob_191

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 13:27:34