如何将含小时DatetimeIndex的Pandas Series重采样至月度并考虑偏移?
问题:将带小时级DatetimeIndex的pandas Series按自定义日起始(06:00)聚合为月度数据
需要把以小时为粒度的时间序列,按日起始为06:00的规则聚合为月度求和数据,即每个月度周期从当月1日06:00开始,到下月1日06:00结束。
示例
构造跨度约1.5个月的小时级序列:
import pandas as pd hours = pd.Series(1, pd.date_range('2020-02-23 06:00', freq='H', periods=1008))
期望得到的月度求和结果:
2020-02-01 06:00:00 168 2020-03-01 06:00:00 744 2020-04-01 06:00:00 96 freq: MS, dtype: int64
已尝试的方法
- 按天重采样时,
offset参数可正常生效,得到正确的日度结果:days = hours.resample('D', offset=pd.Timedelta('06:00:00')).sum() - 直接按月度(
MS)重采样时,结果数值错误且索引缺失时间分量:months = hours.resample('MS', offset=pd.Timedelta('06:00:00')).sum() - 先按天重采样再聚合到月度,数值正确但索引仍缺失时间分量:
days = hours.resample('D', offset=pd.Timedelta('06:00:00')).sum() months = days.resample('MS', offset=pd.Timedelta('06:00:00')).sum() - 临时解决方案:手动给索引添加时间偏移并重置频率,现寻求更优实现:
months.index += pd.Timedelta('06:00:00') months.index.freq = 'MS'
更优解决方案
方法1:时间偏移转换法
通过将时间索引临时偏移,把自定义日起始(06:00)转为标准午夜,再按常规月度重采样,最后还原索引偏移:
# 将原始时间索引向后偏移6小时,使06:00变为午夜 shifted_hours = hours.tshift(-6, freq='H') # 按标准月度初(MS)重采样求和 months = shifted_hours.resample('MS').sum() # 将索引偏移回原自定义起始时间,并保留月度频率 months.index += pd.Timedelta('06:00:00') months.index.freq = 'MS'
该方法逻辑清晰,避免了多次重采样的冗余操作,结果完全符合预期。
方法2:使用带偏移的月度锚点频率
直接使用pd.offsets.MonthBegin指定月度起始的时间偏移,无需手动调整索引:
months = hours.resample(pd.offsets.MonthBegin(offset='6H')).sum()
此方法利用pandas内置的偏移量对象,直接定义自定义的月度周期(每月1日06:00起始),代码更简洁,结果与期望一致。
内容的提问来源于stack exchange,提问作者ElRudi
相关产品推荐
相关产品推荐

