Pandas如何将时间序列观测值替换为对应月份的平均值
实现pandas时间序列按月度均值填充对应观测值
问题背景
存在小时粒度的pandas Series时间序列,构造方式如下:
import pandas as pd import numpy as np pd_series = pd.Series(np.random.rand(26281), index = pd.date_range('2022-01-01', '2024-12-31', freq = 'H')) pd_series
输出样例:
2022-01-01 00:00:00 0.933746 2022-01-01 01:00:00 0.588907 2022-01-01 02:00:00 0.229040 2022-01-01 03:00:00 0.557752 2022-01-01 04:00:00 0.798649 2024-12-30 20:00:00 0.314143 2024-12-30 21:00:00 0.670485 2024-12-30 22:00:00 0.300531 2024-12-30 23:00:00 0.075403 2024-12-31 00:00:00 0.716685 Freq: H, Length: 26281, dtype: float64
需求是将序列中每一条观测值替换为其所属月份的平均值,已知可通过pd_series.resample('MS').mean()计算各月均值,但需要将均值匹配回原序列对应位置。
最优实现方案
直接使用resample配套的transform方法即可,该方法会自动将分组聚合结果广播到分组内的每一行,返回和原序列长度、索引完全一致的结果,无需手动做索引对齐:
# 一步完成月度均值计算+回填到原序列所有对应位置 monthly_avg_series = pd_series.resample('MS').transform('mean')
其他等效实现方式
如果你已经提前单独计算保存了月度均值序列,也可以通过索引重排+前向填充的方式实现:
# 提前计算好的月度均值,索引为每月第一天 monthly_mean = pd_series.resample('MS').mean() # 用原序列索引重排月度均值,前向填充即可把当月第一天的均值填充到整月所有时间点 monthly_avg_series = monthly_mean.reindex(pd_series.index, method='ffill')
注意:该方法仅适用于月度均值采用
MS(每月第一天)作为重采样规则的场景,如果用M(每月最后一天)作为重采样规则,需要把填充方法改为bfill后向填充才能正确匹配。
结果验证
可以通过以下代码确认填充结果正确:
# 提取2022年1月的填充结果,去重后应该只有一个值,即该月的整体均值 print(monthly_avg_series['2022-01'].unique()) # 直接计算原序列2022年1月的均值,和上面的输出应该完全相等 print(pd_series['2022-01'].mean())
内容的提问来源于stack exchange,提问作者W. Walter
相关产品推荐
相关产品推荐

