Pandas如何实现窗口完成后自动重置的rolling滚动最大值计算
Pandas 非重叠重启式滚动窗口最大值实现方案
Pandas原生rolling()接口默认采用连续滑动逻辑,步长固定为1,相邻窗口存在数据重叠。你需要的单窗口计算完成即中断逻辑、重置起点开启下一轮窗口计算的效果,本质是无重叠分块滚动计算,可通过以下两种方案实现。
方法1:基于numpy分块分组实现(性能最优)
核心逻辑是按设定的窗口大小为每一行生成分组标签,同一标签对应一个独立的计算窗口,分组内直接聚合求最大值即可,无额外的滑动计算开销。
import pandas as pd import numpy as np # 构造测试数据集 df = pd.DataFrame({'value': [3, 1, 4, 1, 5, 9, 2, 6]}) window_size = 3 # 可根据需求自定义窗口长度 # 按窗口大小生成分组序号,每个分组对应一个独立的重启窗口 df['block_rolling_max'] = df['value'].groupby( np.arange(len(df)) // window_size ).transform('max')
以上述测试数据、窗口大小3为例,计算得到的结果列为
[4,4,4,9,9,9,6,6],窗口之间无重叠,每段窗口计算完成后直接重置起点开启下一轮计算,尾部不足窗口长度的残段会自动作为独立窗口计算。
方法2:调用原生rolling接口的step参数实现(适配Pandas 1.3+版本)
如果希望沿用rolling接口的调用习惯,可以直接将步长参数step设置为和窗口大小相等,让窗口每次滑动时直接跳过整个窗口长度,达到计算完即重启的效果,最后将聚合结果回填到原表对应位置即可。
window_size = 3 # 步长与窗口大小一致,窗口无重叠,等价于每算完一个窗口就重置起点 rolling_res = df['value'].rolling( window=window_size, step=window_size, min_periods=1 # 设为1可兼容尾部不足窗口长度的残段计算 ).max() # 将窗口计算结果向前填充,匹配原表索引 df['step_rolling_max'] = rolling_res.reindex(df.index, method='ffill')
注意事项
- 若数据使用时间类型索引,需要按固定时间间隔划分重启窗口,可以将分组逻辑替换为对应时间频率的重采样规则,或直接调用
resample接口做分块聚合。 - 两种实现方案性能差异极小,百万行级以内的数据可任意选择;千万行级以上超大数据集优先选择方法1,基于numpy整数分组的计算效率更高。
- 如果需要忽略窗口内的空值,直接在
max()计算时传入skipna=True即可,和Pandas原生聚合参数用法完全一致。
内容的提问来源于stack exchange,提问作者Riddhanand Mohapatra
相关产品推荐
相关产品推荐

