如何用Pandas按完整月份填充分组DataFrame的缺失日期及列值
按用户分组补全指定月份的完整日期
问题:需要给每个用户补全指定月份的所有日期,缺失的数值列填充0。原方法仅能填充数据中现有日期的最小到最大区间,无法覆盖月份首尾的空白日期。
原始数据
import pandas as pd df = pd.DataFrame({ 'user': ['a','a','b','b','c','c','c'], 'dt': ['2016-01-05','2016-01-08', '2016-01-10','2016-01-15','2016-01-16', '2016-01-22', '2016-01-19'], 'val': [1,33,2,1,5,5,6], 'price': [1,2,1,1,2,5.5,4.2] })
原始数据预览:
| user | dt | val | price |
|---|---|---|---|
| a | 2016-01-05 | 1 | 1.0 |
| a | 2016-01-08 | 33 | 2.0 |
| b | 2016-01-10 | 2 | 1.0 |
| b | 2016-01-15 | 1 | 1.0 |
| c | 2016-01-16 | 5 | 2.0 |
| c | 2016-01-22 | 5 | 5.5 |
| c | 2016-01-19 | 6 | 4.2 |
解决方案
核心思路是先生成指定月份的完整日期序列,再和所有用户做笛卡尔积得到全量组合,最后合并原始数据并填充缺失值。
完整代码
import pandas as pd # 处理原始数据的日期格式 df['dt'] = pd.to_datetime(df['dt']) # 定义目标月份,这里是2016年1月 target_month = pd.to_datetime('2016-01-01') # 生成该月份的所有日期(从月初到月末) full_dates = pd.date_range( start=target_month, end=target_month + pd.DateOffset(months=1) - pd.DateOffset(days=1), freq='D' ) # 获取所有唯一用户 unique_users = df['user'].unique() # 构建用户与完整日期的全组合 full_combination = pd.MultiIndex.from_product( [unique_users, full_dates], names=['user', 'dt'] ).to_frame(index=False) # 合并原始数据,缺失值填充为0 result = pd.merge(full_combination, df, on=['user', 'dt'], how='left').fillna(0) # 按用户和日期排序,重置索引 result = result.sort_values(['user', 'dt']).reset_index(drop=True) print(result)
输出结果
输出会包含每个用户对应2016年1月的所有日期,缺失的val和price列自动填充为0,示例片段如下:
user dt val price 0 a 2016-01-01 0.0 0.0 1 a 2016-01-02 0.0 0.0 2 a 2016-01-03 0.0 0.0 3 a 2016-01-04 0.0 0.0 4 a 2016-01-05 1.0 1.0 ... 92 c 2016-01-31 0.0 0.0
内容的提问来源于Stack Exchange,提问作者user177196
相关产品推荐
相关产品推荐

