使用Pandas rolling()计算滚动最大值时,如何排除窗口内前N个值?
解决方案:滚动窗口忽略前N个元素计算最大值
方法一:通用自定义函数法(支持任意N值)
这种方法通过rolling.apply()自定义处理逻辑,能灵活实现“忽略窗口内前N个元素后计算最大值”的需求,适配各种N值和窗口大小的组合。
import pandas as pd # 初始化DataFrame df = pd.DataFrame({'a': [150, 106, 119, 131, 121, 140, 160, 119, 170]}) def max_skip_n(window, n=1): # 窗口元素数量不足以跳过前n个时,返回NaN if len(window) <= n: return pd.NA # 跳过前n个元素后计算最大值 return window[n:].max() # 设置窗口大小为6,忽略前1个元素(n=1) df['b'] = df['a'].rolling(window=6).apply(max_skip_n, args=(1,), raw=True) print(df)
运行结果:
a b 0 150 140.0 1 106 160.0 2 119 160.0 3 131 170.0 4 121 NaN 5 140 NaN 6 160 NaN 7 119 NaN 8 170 NaN
(注:你预期结果中第3行的161应为笔误,实际计算最大值为170)
如果需要忽略前N个元素,只需修改args=(N,)即可,比如忽略前2个元素就设置args=(2,)。
方法二:高效shift+rolling法(适合固定N值)
当N值固定时,可通过shift()和rolling()结合的方式避免自定义函数的开销,运行效率更高。
以忽略前1个元素、窗口大小6为例:窗口内忽略第一个元素,等价于取当前位置之后的5个元素的最大值,因此可以将原数据后移1位,再取窗口大小为5的滚动最大值:
import pandas as pd df = pd.DataFrame({'a': [150, 106, 119, 131, 121, 140, 160, 119, 170]}) # 后移1位,再取窗口大小为5的滚动最大值 df['b'] = df['a'].shift(-1).rolling(window=5).max() print(df)
运行结果和方法一完全一致。
通用化公式:若窗口大小为k,忽略前N个元素,则等价于取当前位置后移N位的数据,再取窗口大小为k-N的滚动最大值:
# 示例:窗口大小k=6,忽略前N=2个元素 df['b'] = df['a'].shift(-2).rolling(window=6-2).max()
为什么你的尝试无效?
- attempt 1:
df.a.shift(-1).rolling(6).max()将窗口大小设为6,导致每个位置取的是后移1位后连续6个元素的最大值,和需求的“原窗口6个元素忽略第一个”不符。 - attempt 2:
closed='left'仅控制窗口闭合方向,并没有忽略窗口内的第一个元素,逻辑不符合需求。 - attempt 3:循环切片的方式没有将计算结果赋值给
df['b'],且未处理窗口长度不足的情况,无法得到完整结果。
内容的提问来源于stack exchange,提问作者AmirX
相关产品推荐
相关产品推荐

