为Python Pandas DataFrame按日期-ID组合向前填充缺失月末日期
多ID场景下的日期向前填充实现方案
问题背景
原始Pandas DataFrame如下:
import pandas as pd df = pd.DataFrame({ 'Date': ['2015-01-31','2015-01-31', '2015-02-28', '2015-03-31', '2015-04-30', '2015-04-30'], 'ID': [1,2,2,2,1,2], 'value': [1,2,3,4,5,6] }) print(df)
输出:
Date ID value 0 2015-01-31 1 1 1 2015-01-31 2 2 2 2015-02-28 2 3 3 2015-03-31 2 4 4 2015-04-30 1 5 5 2015-04-30 2 6
需要实现的需求:为每个ID补充截至2015-05-31的所有月末日期记录,缺失日期的value用该ID最近的有效值向前填充,最终期望结果如下:
Date ID value 0 2015-01-31 1 1 1 2015-01-31 2 2 2 2015-02-28 2 3 3 2015-02-28 1 1 4 2015-03-31 2 4 5 2015-03-31 1 1 6 2015-04-30 1 5 7 2015-04-30 2 6 8 2015-05-31 1 5 9 2015-05-31 2 6
实现方案
可以通过构建完整的日期-ID组合网格,再按ID分组向前填充的方式实现,具体步骤如下:
1. 处理日期格式并生成目标日期范围
先将Date列转为datetime类型,再生成从数据最早日期到2015-05-31的所有月末日期:
# 转换日期为datetime类型 df['Date'] = pd.to_datetime(df['Date']) # 生成目标月末日期范围 start_date = df['Date'].min() end_date = pd.to_datetime('2015-05-31') target_dates = pd.date_range(start=start_date, end=end_date, freq='M')
2. 构建日期与ID的完整组合
提取所有唯一ID,生成日期和ID的笛卡尔积,确保每个ID在每个目标日期都有对应记录:
# 获取所有唯一ID unique_ids = df['ID'].unique() # 生成日期-ID的完整多级索引 full_index = pd.MultiIndex.from_product([target_dates, unique_ids], names=['Date', 'ID'])
3. 重新索引并按ID向前填充
将原始数据设置为多级索引,对齐到完整索引后,按ID分组向前填充缺失值:
# 为原始数据设置多级索引 df = df.set_index(['Date', 'ID']) # 重新索引并按ID向前填充 filled_df = df.reindex(full_index).groupby('ID').ffill().reset_index() # 打印结果 print(filled_df)
关键逻辑说明
pd.date_range(..., freq='M'):自动生成指定区间内的所有月末日期,无需手动枚举。MultiIndex.from_product:构建日期和ID的所有可能组合,保证每个ID在每个日期都有记录。groupby('ID').ffill():按ID分组后执行向前填充,确保每个ID的缺失值仅用自身历史有效值填充,不会跨ID干扰。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

