如何在Pandas中计算排除当前行日期的滚动平均窗口?
问题
现有如下Pandas DataFrame:
import pandas as pd df = pd.DataFrame( {"date": [pd.Timestamp("2022-01-01"), pd.Timestamp("2022-01-01"), pd.Timestamp("2022-01-01"), pd.Timestamp("2022-01-03"), pd.Timestamp("2022-01-05")], "numbers": [1,2,3,4,5] } )
需要计算每行date对应日期之前的numbers字段3天滚动均值。尝试过df["av"] = df.shift(1).rolling(window=3).mean(),但这个方法是按固定行数滚动,没法根据日期动态偏移,还会错误包含当日数据。
预期输出(3天窗口下的av列):
date numbers av 0 2022-01-01 1 NaN 1 2022-01-01 2 NaN 2 2022-01-01 3 NaN 3 2022-01-03 4 2.0 4 2022-01-03 7 2.0 5 2022-01-05 5 5.5
解决方法
用Pandas的时间滚动窗口功能,结合分组映射就能实现需求,代码如下:
# 先按日期排序,确保时间顺序正确 df = df.sort_values('date') # 将date设为索引,方便基于时间的滚动计算 df_indexed = df.set_index('date') # 计算3天滚动均值,closed='left'表示窗口不包含当前日期 rolling_means = df_indexed.rolling(window='3D', closed='left')['numbers'].mean() # 同一日期的所有行共用同一个均值,所以先按日期分组取唯一值,再映射回原表 df['av'] = df['date'].map(rolling_means.groupby(level=0).first()) # 输出结果 print(df)
关键细节:
window='3D':用时间长度(3天)代替固定行数,实现动态的日期窗口,而不是固定取前3行closed='left':这是核心参数,它让滚动窗口只包含当前日期之前的数据,彻底排除当日记录groupby(level=0).first():同一日期的多行数据对应的均值是一样的,通过这个操作提取每个日期的唯一均值,再映射回原DataFrame,保证同一日期的行结果一致
内容的提问来源于stack exchange,提问作者Ben Muller
相关产品推荐
相关产品推荐

