Python rolling():移动窗口计算(附带实例)
Python 中,通过重采样我们可以得到想要的任何频率的数据,但是这些数据也是某个时间点的数据,因此存在这样一个问题,基于时间点的数据波动较大时,某一点的数据就不能很好地表现该事物的本身的特性。于是就有了“移动窗口”的概念,简单地说,为了提升数据的可靠性,将某个取值点扩大到包含这个点的一段区间,这个区间就是窗口。
举例说明,如下图所示,其中时间序列代表某月 1 号到 15 号每天的销量数据,接下来以 3 天为一个窗口,将该窗口从左至右依次移动,统计出 3 天的均值作为某个时间点的值,比如 3 号的销量是 1 号、2 号和 3 号销量的均值。

图 1 移动窗口示意图
通过图 1,相信你已经理解了移动窗口。在 Pandas 中可以通过 rolling() 函数实现移动窗口数据计算,语法格式如下:
【实例】创建淘宝每日销量数据。
1) 首先模拟一组淘宝每日销量数据,程序代码如下:
2) 使用 rolling() 方法计算 2024-02-01 到 2024-02-15 期间每 3 天的均值,即窗口长度为 3,主要代码如下:

图 2 2024-02-01 到 2024-02-15 的移动窗口均值1
当窗口开始移动时,第 1 个时间点 2024-02-01 和第 2 个时间点 2024-02-02 的数值为空值,这是因为窗口长度为 3,前面有空数据;而到第 3 个时间点 2024-02-03,它前面的数据是 2024-02-01 到 2024-02-03,所以 3 天的均值是 533.333333,以此类推。
3) 在计算第 1 个时间点 2024-02-01 的窗口数据时,虽然数据个数不够窗口长度 3,但至少有当天的数据,那么能否用当天的数据代表窗口数据呢?答案是肯定的,通过设置 min_periods 参数即可,它表示窗口中最少包含的观测值,小于这个值的窗口长度显示为空值,大于或等于时都有值,主要代码如下:

图 3 2024-02-01 到 2024-02-15 的移动窗口均值2
扩展上述示例,通过图表观察原始数据与移动窗口数据的平稳性,如下图所示:

图 4 移动窗口数据的平稳性
举例说明,如下图所示,其中时间序列代表某月 1 号到 15 号每天的销量数据,接下来以 3 天为一个窗口,将该窗口从左至右依次移动,统计出 3 天的均值作为某个时间点的值,比如 3 号的销量是 1 号、2 号和 3 号销量的均值。

图 1 移动窗口示意图
通过图 1,相信你已经理解了移动窗口。在 Pandas 中可以通过 rolling() 函数实现移动窗口数据计算,语法格式如下:
DataFrame.rolling(window, min_periods=None, center=False, win_type=None, on=None, closed=None, step=None, method='single')参数说明见下表:
参数 | 说明 |
---|---|
window | 整型、日期时间间隔对象、字符串、偏移量、BaseIndexer 子类,表示窗口移动的大小。如果是整型,则表示每个窗口的固定观测数;如果是日期时间间隔对象、字符串或偏移量,则表示每个窗口的时间段。每个窗口的大小将随着时间段内的观测值变化而变化,只对类似日期时间的索引有效;如果是 BaseIndexer 子类,则窗口边界的定义将基于 get_window_bounds() 方法 |
min_periods | 整型,默认值为 None,表示每个窗口最少包含的观测值数量,小于这个值的窗口结果为 NA。由偏移量指定的窗口,默认值为 1;由整数指定的窗口,默认值为窗口的大小 |
center | 布尔值,默认值为 False。如果参数值为 False,则将窗口标签设置为窗口索引的右侧边缘;如果参数值为 True,则将窗口标签设置为窗口索引的中心 |
win_type | 字符串,默认值为 None。如果参数值为 None,则所有点都是均匀加权的;如果参数值为字符串,则必须是一个有效的变量,即窗口函数(scipy.signal.windows) |
on | 字符串,可选参数。对于 DataFrame 对象,要在其上计算移动窗口的列标签或索引级别。如果提供的是整数索引,其将被忽略并从结果中排除,因为整数索引不能用于计算移动窗口数据 |
closed |
字符串,默认值为 None(right),参数值介绍如下:
|
step | 计算每个移动步骤产生的窗口数据 |
method | 字符串,参数值为 single 或 table,默认值为 single,表示对单行/列执行移动操作;参数值为 table 表示对整个对象执行移动操作 |
返回值 | 为特定操作而生成的窗口或移动窗口子类 |
值得一提的是,Series 对象中也有 rolling() 方法,用法与 DataFrame 对象中的一样。
【实例】创建淘宝每日销量数据。
1) 首先模拟一组淘宝每日销量数据,程序代码如下:
# 导入pandas模块 import pandas as pd # 创建日期数据 index=pd.date_range(start='20240201',end='20240215') data=[300,600,700,400,209,1187,335,88,999,1100,112,515,613,222,114] # 创建Series对象 sl_data=pd.Series(data,index=index) print(sl_data)
2) 使用 rolling() 方法计算 2024-02-01 到 2024-02-15 期间每 3 天的均值,即窗口长度为 3,主要代码如下:
print(sl_data.rolling(3).mean())运行程序,看一下 rolling() 方法是如何计算的。如下图所示:

图 2 2024-02-01 到 2024-02-15 的移动窗口均值1
当窗口开始移动时,第 1 个时间点 2024-02-01 和第 2 个时间点 2024-02-02 的数值为空值,这是因为窗口长度为 3,前面有空数据;而到第 3 个时间点 2024-02-03,它前面的数据是 2024-02-01 到 2024-02-03,所以 3 天的均值是 533.333333,以此类推。
3) 在计算第 1 个时间点 2024-02-01 的窗口数据时,虽然数据个数不够窗口长度 3,但至少有当天的数据,那么能否用当天的数据代表窗口数据呢?答案是肯定的,通过设置 min_periods 参数即可,它表示窗口中最少包含的观测值,小于这个值的窗口长度显示为空值,大于或等于时都有值,主要代码如下:
print(sl_data.rolling(window=3, min_periods=1).mean())运行程序,结果如下图所示:

图 3 2024-02-01 到 2024-02-15 的移动窗口均值2
扩展上述示例,通过图表观察原始数据与移动窗口数据的平稳性,如下图所示:

图 4 移动窗口数据的平稳性
其中实线代表移动窗口数据,其走向更平稳,这也是我们学习移动窗口 rolling() 方法的原因。虚线代表原始数据,实线代表移动窗口数据。