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

pandas.Rolling中'on'参数作用及滚动窗口排序疑问

关于pandas rolling窗口与on参数的疑问解答

问题背景

用户的示例代码与数据:

import pandas as pd
df = pd.DataFrame({"values": [3,2,1,1000,1,3,1],"day":[1,2,3,1,2,3,1]})

输出的初始DataFrame:

values  day
0       3    1
1       2    2
2       1    3
3    1000    1
4       1    2
5       3    3
6       1    1

需求为:找出连续2个同day分组的最大值。

用户尝试两种方法后出现困惑:

  1. 先按day排序再执行滚动:df.sort_values("day").rolling(2).sum().sort_index() 得到预期结果
  2. 使用on参数执行滚动:df.rolling(2,on="day").max() 结果不符合预期,输出如下:
values    day
0     NaN    1.0
1     3.0    2.0
2     2.0    3.0
3  1000.0    1.0
4  1000.0    2.0
5     3.0    3.0
6     3.0    1.0

核心原因解析

1. rolling窗口的本质是按行的物理位置滑动

不管是否使用on参数,rolling窗口都是基于DataFrame的当前行顺序来滑动的,不会自动对数据做排序或分组。

排序后生效的原因是:排序操作将同day的行连续排列,此时rolling(2)会把相邻的同day数据纳入同一个窗口,自然能计算出同day连续两个数据的聚合结果。

2. on参数的真实作用

pandas文档中on参数的描述容易产生误解,它的真实功能是:

  • 仅用于确定窗口的数值/时间边界(比如时间序列中按固定日期间隔划分窗口),而非帮你对数据分组或排序。
  • 当指定on="day"时,pandas会基于day列的值判断窗口是否符合大小要求,但不会改变原有行的顺序。例如原数据中行0(day1)与行3(day1)物理上不相邻,rolling(2,on="day")不会将这两行放入同一个窗口。

3. 排序后索引未变但生效的原因

df.sort_values("day")仅改变了行的物理排列顺序,索引虽然保留原值,但rolling窗口的滑动逻辑只关心当前行的先后顺序,与索引本身的数值无关。排序后原索引0、3、6的行被连续排列,rolling(2)会依次计算这三行中相邻两行的最大值,最后sort_index()只是将行序恢复为原索引顺序而已。

推荐实现方式

如果需要按day分组后每组内做滚动窗口计算,更准确的写法是结合groupby与rolling:

# 按day分组,每组内计算2个数据的滚动最大值
df["rolling_max"] = df.groupby("day")["values"].rolling(2).max().reset_index(level=0, drop=True)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 23:43:40