按组扩展非平衡月度数据:补全分组内起止日期间的月末日期
问题解决:按分组补全月末日期
问题描述
有一个包含月度数据的DataFrame示例如下:
df = pd.DataFrame({'date': ['2010-02-28', '2010-04-30', '2010-01-31', '2010-03-31'], 'group': ['A', 'A', 'B', 'B']})
需要为每个分组补全其自身起止日期之间的所有月末日期(各分组起止日期不同),但原代码执行后所有分组的起止日期一致,且new_date与group的组合存在重复:
df['new_date'] = df.apply(lambda x: pd.date_range(start='2010-01-31', end='2010-04-30', freq = 'M'), axis=1) df = df.explode('new_date').reset_index(drop=True)
原代码问题分析
- 硬编码固定起止日期,未根据每个分组的实际数据计算专属范围,导致所有分组日期序列完全一致
- 原DataFrame每个分组包含两行数据,
apply会为每一行生成完整日期序列,explode后自然出现重复的group+new_date组合
解决方案
先转换日期列为datetime类型,再按分组计算各自的起止日期,生成对应月末序列:
import pandas as pd # 初始化数据 df = pd.DataFrame({'date': ['2010-02-28', '2010-04-30', '2010-01-31', '2010-03-31'], 'group': ['A', 'A', 'B', 'B']}) # 转换日期列为datetime类型,确保日期计算正常 df['date'] = pd.to_datetime(df['date']) # 按分组生成专属的完整月末日期序列 result = df.groupby('group').apply( lambda group: pd.DataFrame({ 'group': group.name, 'new_date': pd.date_range(start=group['date'].min(), end=group['date'].max(), freq='M') }) ).reset_index(drop=True) print(result)
输出结果
group new_date 0 A 2010-02-28 1 A 2010-03-31 2 A 2010-04-30 3 B 2010-01-31 4 B 2010-02-28 5 B 2010-03-31
代码说明
groupby('group'):按分组独立处理每个组的数据group['date'].min()/group['date'].max():获取当前分组的实际起止日期,保证每个组的日期范围贴合自身数据pd.date_range(..., freq='M'):生成起止日期之间的所有月末日期,精准匹配月度数据需求reset_index(drop=True):清理分组后产生的多级索引,得到结构整洁的最终结果
内容的提问来源于stack exchange,提问作者Warrior
相关产品推荐
相关产品推荐

