关于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,两者的计算窗口方向正好相反:
如果你想固定窗口的方向(不管索引顺序如何,都保持向后/向前看),也有办法:比如在升序索引下,结合rolling("60min", closed='both')或者shift()来调整,但默认的行为就是跟着索引顺序走的——刚好满足了你需要的双向窗口计算需求,是不是很贴心?
备注:内容来源于stack exchange,提问作者echti123
相关产品推荐
相关产品推荐

