如何用Pandas为各ID补全所有已存在日期并填充上一条记录?
补全DataFrame中每个ID的缺失日期并填充上一条记录值
当然有简便的方法实现这个需求!核心思路是先构建包含所有ID和所有已出现日期的完整索引,再和原数据合并,最后用**向前填充(forward fill)**来补全缺失的特征值。下面是具体步骤和代码:
步骤1:准备并清洗数据
首先加载数据,同时清理日期字段的前导空格(避免后续匹配出错),如果需要的话还可以把日期转成datetime类型,确保排序逻辑更准确:
import pandas as pd # 原始数据 data = [{"id":1,"date":" 1-1-2001","f1":1,"f2":0,"f3":1},{"id":1,"date":" 2-1-2001","f1":2,"f2":1,"f3":1},{"id":1,"date":" 3-1-2001","f1":3,"f2":1,"f3":1},{"id":2,"date":" 1-1-2001","f1":1,"f2":0,"f3":1},{"id":2,"date":" 3-1-2001","f1":3,"f2":2,"f3":1},{"id":3,"date":" 1-1-2001","f1":1,"f2":0,"f3":1},{"id":3,"date":" 2-1-2001","f1":5,"f2":3,"f3":3}] df = pd.DataFrame(data) # 清理日期的前导空格 df['date'] = df['date'].str.strip() # 可选:将日期转为datetime类型,避免字符串排序的逻辑错误(比如"10-1-2001"和"2-1-2001"的排序问题) df['date'] = pd.to_datetime(df['date'], format='%d-%m-%Y')
步骤2:构建完整的ID-日期索引
生成所有唯一ID和所有唯一日期的笛卡尔积,确保每个ID都能覆盖数据集中出现过的所有日期:
# 获取所有唯一的ID和日期 unique_ids = df['id'].unique() unique_dates = df['date'].unique() # 生成笛卡尔积,得到包含所有ID+日期组合的DataFrame full_index = pd.MultiIndex.from_product([unique_ids, unique_dates], names=['id', 'date']) full_df = pd.DataFrame(index=full_index).reset_index()
步骤3:合并数据并填充缺失值
将原数据和完整索引合并,然后按ID分组,用ffill()(向前填充)补全缺失的特征值——这样每个缺失的日期行就会用该ID最近的上一条已有记录来填充:
# 合并原数据和完整索引 merged_df = pd.merge(full_df, df, on=['id', 'date'], how='left') # 按ID和日期排序,分组后向前填充缺失值 result_df = merged_df.sort_values(['id', 'date']) \ .groupby('id') \ .ffill() \ .reset_index(drop=True) # 如果需要把日期转回字符串格式(和原数据一致),可以用: # result_df['date'] = result_df['date'].dt.strftime('%d-%m-%Y') print(result_df)
结果说明
运行上述代码后,得到的result_df完全符合你的需求:每个ID都包含了数据集中所有已出现的日期,缺失的特征值会用该ID最近的上一条记录填充,且不会生成数据集中不存在的日期。
内容的提问来源于stack exchange,提问作者NaT3z
相关产品推荐
相关产品推荐

