在pandas中为不同起止日期的项目补全连续日期行
问题:按项目补全日期范围内的缺失记录
我有一个记录项目工作数据的DataFrame data,结构如下:
import pandas as pd project = ['Project 1','Project 1','Project 1','Project 1','Project 2','Project 2','Project 2','Project 3','Project 3','Project 3','Project 4','Project 5','Project 5','Project 5'] date = ['2010-10-12','2010-10-15','2010-10-20','2010-10-22','2012-05-05','2012-05-07','2012-05-10','2018-01-01','2018-01-05','2018-01-06','2019-10-02','2010-02-02','2010-02-04','2010-02-07'] date = pd.to_datetime(date) hours = [0,1,0,2,4,0,2,1,0,2,4,2,4,3] taskcount = [0,1,2,0,1,2,0,1,2,0,1,0,0,2] data = pd.DataFrame({'Project':project, 'Date':date, 'Hours':hours,'TaskCount':taskcount})
其中Hours列记录当日工作时长,TaskCount列记录当日完成任务数。
另外还有存储各项目起止日期的project_duration DataFrame:
column_DateFirstRecord = data.groupby('Project').apply(lambda df: df.Date.min()) column_DateLastRecord = data.groupby('Project').apply(lambda df: df.Date.max()) project_duration = pd.concat([column_DateFirstRecord, column_DateLastRecord], axis=1) project_duration.columns = ['DateFirstRecord', 'DateLastRecord'] project_duration = project_duration.assign(ProjectLength = (project_duration.DateLastRecord - project_duration.DateFirstRecord))
需求是:为每个项目补全其首条记录日期到末条记录日期之间的所有缺失日期行,新补行的Hours和TaskCount设为0(示例输出见问题描述)。实际处理数据量约27.8万行,需要高效方案,之前尝试的分组补全方法不支持不同项目的自定义起止日期。
高效解决方案
步骤1:优化项目起止日期生成
用groupby.agg替代原有的apply方法生成起止日期,减少循环开销:
# 生成项目起止日期,比原apply方法更高效 project_duration = data.groupby('Project')['Date'].agg(['min', 'max']).rename( columns={'min': 'DateFirstRecord', 'max': 'DateLastRecord'} ) project_duration['ProjectLength'] = project_duration['DateLastRecord'] - project_duration['DateFirstRecord']
步骤2:生成每个项目的完整日期序列
通过apply生成每个项目的日期范围,再用explode展开成逐行记录,避免逐组循环:
# 为每个项目生成包含所有日期的序列 project_duration['DateRange'] = project_duration.apply( lambda row: pd.date_range(start=row['DateFirstRecord'], end=row['DateLastRecord'], freq='D'), axis=1 ) # 展开日期序列,得到项目与日期的全量组合 full_dates = project_duration.explode('DateRange').reset_index()[['Project', 'DateRange']].rename(columns={'DateRange': 'Date'})
步骤3:合并原数据并填充缺失值
用merge进行向量化合并,再批量填充缺失值为0,确保数值类型正确:
# 合并全量日期与原数据,左连接保留所有日期行 data_output = full_dates.merge(data, on=['Project', 'Date'], how='left') # 填充缺失的工作时长和任务数为0 data_output[['Hours', 'TaskCount']] = data_output[['Hours', 'TaskCount']].fillna(0).astype(int)
方案优势
- 避免逐组循环的低效操作,全部采用Pandas向量化API处理
groupby.agg、explode、merge都是Pandas针对大数据量优化的方法,适配27.8万行级别的数据处理- 逻辑清晰,代码简洁易维护
内容的提问来源于stack exchange,提问作者blargen
相关产品推荐
相关产品推荐

