如何基于时间序列索引计算前5年同日期的滚动均值?
针对时间序列前5年同日期均值的解决方案
实现思路
核心逻辑是按「月-日」分组,在每个组内按年份顺序取前5个历史同日期数据(不含当前年份)计算均值,最终将结果作为新列添加到原数据中。
完整代码
首先生成测试数据:
import numpy as np import pandas as pd np.random.seed(1) rows, cols = 4950, 5 data = np.random.rand(rows, cols) tidx = pd.date_range('2010-01-01', periods=rows, freq='D') df = pd.DataFrame(data, columns=['a','b','c','d','e'], index=tidx)
执行均值计算:
# 1. 添加月日分组标识,用于按相同月日聚合 df['month_day'] = df.index.strftime('%m-%d') # 2. 定义计算函数:对分组内的序列,取前5期(不含当前行)的均值 def rolling_5y_mean(series): return series.rolling(window=5, closed='left').mean() # 3. 按月日分组,计算各列的前5年同日期均值 avg_result = df.groupby('month_day')[['a', 'b', 'c', 'd', 'e']].apply(rolling_5y_mean) # 4. 重命名均值列,匹配A_Avg这类格式 avg_result.columns = [col.upper() + '_Avg' for col in avg_result.columns] # 5. 合并均值列到原数据,清理临时分组列 df = pd.concat([df, avg_result], axis=1) df.drop('month_day', axis=1, inplace=True)
结果验证
以2015-01-01为例,验证计算结果准确性:
target_date = pd.Timestamp('2015-01-01') # 手动提取2010-2014年1月1日的a列数据 prev_5y_data = df.loc[(df.index.year >= target_date.year -5) & (df.index.year < target_date.year) & (df.index.month == 1) & (df.index.day == 1), 'a'] manual_avg = prev_5y_data.mean() print(f"手动计算均值:{manual_avg:.6f}") print(f"代码计算均值:{df.loc[target_date, 'A_Avg']:.6f}")
关键说明
rolling(window=5, closed='left'):窗口大小设为5且排除当前行,刚好匹配「前5年同日期」需求(比如2023年的日期,自动取2018-2022年的同日期数据)。- 按「月-日」分组确保每个日期的均值计算仅针对相同月日的历史数据,避免跨日期混淆。
内容的提问来源于stack exchange,提问作者thesimplevoodoo
相关产品推荐
相关产品推荐

