You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas实现混合频率时间区间数据的月度均值计算

多频率重叠时间周期月度求和实现方案

pd.Grouper 仅支持固定频率、无重叠区间的时间分组逻辑,无法直接处理跨月度/季度/年度的重叠区间匹配需求,可通过区间逐次匹配的方式实现,步骤如下:

1. 数据预处理

首先将多层索引的字符串日期转换为标准datetime格式,方便后续日期比较:

import pandas as pd
import numpy as np

# 构造和提问完全对齐的样例数据
multi_index = pd.MultiIndex.from_tuples([("2022-01-01", "2022-12-31"), 
                                  ("2022-01-01", "2022-03-30"), 
                                  ("2022-03-01", "2022-03-30"),
                                  ("2022-04-01", "2022-04-30")])
multi_index.names = ['period_begin', 'period_end']
df = pd.DataFrame([4,3,5,8], index=multi_index, columns=['value'])

# 索引转列+日期格式转换
df = df.reset_index()
df['period_begin'] = pd.to_datetime(df['period_begin'])
df['period_end'] = pd.to_datetime(df['period_end'])

2. 生成连续月度索引

提取数据覆盖的最早、最晚时间边界,生成每月第一天为节点的连续时间序列,作为结果的索引:

min_dt = df['period_begin'].min()
max_dt = df['period_end'].max()
# 频率MS代表每月第一天
month_list = pd.date_range(start=min_dt, end=max_dt, freq='MS')

3. 逐月份匹配覆盖区间求和

遍历每个月度节点,筛选所有时间范围覆盖当月的观测值求和即可。

注意:提问样例里的季度、月度周期结束日期没有取自然月最后一天(比如3月周期结束写为3月30日而非3月31日),因此筛选条件调整为:观测起始日早于/等于当月第一天,且观测结束日晚于/等于当月第一天,即可正确匹配覆盖当月的所有周期,不会出现漏匹配。

res = []
for month_start in month_list:
    # 筛选覆盖当月的所有观测
    cover_mask = (df['period_begin'] <= month_start) & (df['period_end'] >= month_start)
    month_sum = df.loc[cover_mask, 'value'].sum()
    res.append({'month_begin': month_start, 'Monthly_Avg': month_sum})

# 转换为目标格式
result_df = pd.DataFrame(res).set_index('month_begin')

结果说明

运行后得到的结果完全符合给定计算规则:

Monthly_Avg
month_begin             
2022-01-01             7
2022-02-01             7
2022-03-01            12
2022-04-01            12
2022-05-01             4
2022-06-01             4
2022-07-01             4
2022-08-01             4
2022-09-01             4
2022-10-01             4
2022-11-01             4
2022-12-01             4

其中1-2月为年值+一季度值之和(4+3=7),3月为年值+一季度值+3月单月值之和(4+3+5=12),4月为年值+4月单月值之和(4+8=12),5-12月仅叠加年值4。如果实际数据里周期结束日期严格取自然周期最后一天,只需要把筛选条件里的df['period_end'] >= month_start替换为df['period_end'] >= month_start + pd.offsets.MonthEnd(0)即可。

内容的提问来源于stack exchange,提问作者W. Walter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 09:30:46