Pandas时间戳DataFrame未来/向后窗口绝对偏差滚动中位数计算
Pandas 计算时间序列未来5秒内值与当前值绝对差的中位数
给定一个以时间戳为索引的pandas DataFrame,需要为每个数据点计算未来5秒内所有值(含当前值)与当前值的绝对差的中位数。示例数据如下:
import pandas as pd df = pd.DataFrame({'A': [2, 1, 3, 4, -1, 2, -3, 5, 4, -10]}, index=pd.date_range('2022-01-01', periods=10, freq='s'))
以第一个数据点(索引2022-01-01 00:00:00)为例:未来5秒内的数值为[2, 1, 3, 4, -1, 2],与当前值2的绝对差为[0, 1, 1, 2, 3, 0],其中位数为1。
方法一:直接使用向前滚动窗口
利用pandas的rolling函数,指定direction='forward'实现向前看未来的窗口,搭配自定义函数计算绝对差的中位数:
# 计算未来5秒窗口(含当前点)的绝对差中位数 result_forward = df['A'].rolling( window='5s', closed='both', direction='forward' ).apply(lambda x: x.sub(x.iloc[0]).abs().median()) print(result_forward)
window='5s':定义时间窗口为5秒closed='both':窗口包含当前时间点和刚好5秒后的点direction='forward':窗口方向为向前(未来)
方法二:反向处理(向后窗口,更简洁高效)
由于pandas默认滚动窗口是向后看历史数据,我们可以通过反转数据将"未来窗口"转换为"历史窗口"处理,最后再反转结果:
# 反转数据行顺序 df_reversed = df.iloc[::-1] # 用默认向后窗口计算(等价于原数据的未来窗口) result_reversed = df_reversed['A'].rolling( window='5s', closed='both' ).apply(lambda x: x.sub(x.iloc[0]).abs().median()) # 反转结果得到原数据的未来窗口计算值 result_backward = result_reversed.iloc[::-1] print(result_backward)
这种方法避免了指定direction参数,兼容更早版本的pandas,且性能表现更稳定。
注意事项
- 数据索引必须是
DatetimeIndex,若频率不固定,时间窗口仍能自动识别5秒内的所有数据点 - 若不需要包含当前点,可将
closed参数改为'right' - 自定义
apply函数在超大数据集上可能有性能瓶颈,若需优化可考虑向量化实现(复杂度较高)
内容的提问来源于stack exchange,提问作者SBF
相关产品推荐
相关产品推荐

