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

关于pandas.DataFrame.rolling()时间窗口迭代行为的确认:是Bug还是特性?

关于pandas.DataFrame.rolling()时间窗口迭代行为的确认:是Bug还是特性?

嘿,这事儿我门儿清!先给你吃定心丸:你观察到的这个时间窗口方向随索引排序变化的行为,是pandas的原生设计特性,绝对不是Bug。

咱们来拆解一下背后的逻辑:
pandas的rolling()时间窗口计算,核心是跟着索引的顺序走的。默认情况下:

  • 当索引是升序时,当前行的时间是序列里的较晚时间,rolling("60min")会自动取「当前时间往前60分钟」的数据——也就是你说的“向后看”窗口;
  • 当你把DataFrame倒序(df.iloc[::-1].copy())后,索引的顺序完全反过来了:当前行的时间变成了序列里的较早时间,这时候窗口就会取「当前时间往后60分钟」的数据——看起来就像“向前看”了。
    本质上,rolling()的窗口始终是在当前行在序列中的位置的逆方向扩展时间范围,完全符合pandas适配不同索引排序场景的设计逻辑。

先看你用来复现的测试代码:

import pandas as pd
import datetime as dt

data = [
    {'Timestamp': dt.datetime(2025, 1, 13, 19, 45), 'number': 2255},
    {'Timestamp': dt.datetime(2025, 1, 13, 19, 50), 'number': 1490},
    {'Timestamp': dt.datetime(2025, 1, 13, 19, 55), 'number': 723},
    {'Timestamp': dt.datetime(2025, 1, 13, 20, 0), 'number': 289},
    {'Timestamp': dt.datetime(2025, 1, 13, 20, 5), 'number': 4647},
    {'Timestamp': dt.datetime(2025, 1, 13, 20, 10), 'number': 4753},
    {'Timestamp': dt.datetime(2025, 1, 13, 20, 15), 'number': 1915},
    {'Timestamp': dt.datetime(2025, 1, 13, 20, 20), 'number': 2379},
    {'Timestamp': dt.datetime(2025, 1, 13, 20, 25), 'number': 198},
    {'Timestamp': dt.datetime(2025, 1, 13, 20, 30), 'number': 4270},
    {'Timestamp': dt.datetime(2025, 1, 13, 20, 35), 'number': 2734},
    {'Timestamp': dt.datetime(2025, 1, 13, 20, 40), 'number': 2365},
    {'Timestamp': dt.datetime(2025, 1, 13, 20, 45), 'number': 4261},
    {'Timestamp': dt.datetime(2025, 1, 13, 20, 50), 'number': 1428},
    {'Timestamp': dt.datetime(2025, 1, 13, 20, 55), 'number': 3672},
    {'Timestamp': dt.datetime(2025, 1, 13, 21, 0), 'number': 4588},
    {'Timestamp': dt.datetime(2025, 1, 13, 21, 5), 'number': 3675},
    {'Timestamp': dt.datetime(2025, 1, 13, 21, 10), 'number': 1304},
    {'Timestamp': dt.datetime(2025, 1, 13, 21, 15), 'number': 3854},
    {'Timestamp': dt.datetime(2025, 1, 13, 21, 20), 'number': 979},
    {'Timestamp': dt.datetime(2025, 1, 13, 22, 15), 'number': 1468},
    {'Timestamp': dt.datetime(2025, 1, 13, 23, 30), 'number': 3178},
    {'Timestamp': dt.datetime(2025, 1, 13, 23, 35), 'number': 2910},
    {'Timestamp': dt.datetime(2025, 1, 13, 23, 40), 'number': 4780},
    {'Timestamp': dt.datetime(2025, 1, 13, 23, 45), 'number': 717},
    {'Timestamp': dt.datetime(2025, 1, 13, 23, 50), 'number': 4113},
    {'Timestamp': dt.datetime(2025, 1, 13, 23, 55), 'number': 4927},
]

df = pd.DataFrame(data)
df.set_index('Timestamp', inplace=True)
df["mean_asc"] = df["number"].rolling("60min").mean()
df = df.iloc[::-1].copy()
df["mean_desc"] = df["number"].rolling("60min").mean()

运行这段代码后,你会得到包含mean_asc(升序索引下的滚动均值)和mean_desc(降序索引下的滚动均值)的DataFrame,两者的计算窗口方向正好相反:
处理后的DataFrame结果

如果你想固定窗口的方向(不管索引顺序如何,都保持向后/向前看),也有办法:比如在升序索引下,结合rolling("60min", closed='both')或者shift()来调整,但默认的行为就是跟着索引顺序走的——刚好满足了你需要的双向窗口计算需求,是不是很贴心?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 13:57:59