优化Pandas DataFrame缺失日期补全:提升大数据集处理速度
优化百万级数据集下Pandas补全分组缺失日期的性能
我有一个包含2个不同门店的Pandas DataFrame,需要补全2023-11-09至2023-11-14期间的缺失日期。参考相关方案实现了以下代码:
dates = mydf.groupby(['STORE','ADDRESS'])['DATE'].nunique() # Create MultiIndex with separate Date ranges per Group midx = pd.MultiIndex.from_frame( dates.apply( lambda x: pd.date_range('2023-11-09', '2023-11-14', freq='D'), axis=1 ).explode().reset_index(name='DATE')[['DATE', 'STORE', 'ADDRESS']] ) # Reindex mydf = ( mydf.set_index(['DATE', 'STORE', 'ADDRESS']) .reindex(midx, fill_value=0) .reset_index() )
同时尝试了自定义函数:
def filling_missing_dates(df): import pandas as pd df['DATE']= pd.to_datetime(df['DATE']) group = df.groupby(['STORE','ADDRESS']).nunique() a = [pd.date_range('2023-11-09', '2023-11-14', freq='D')] b = [] b.extend(a * len(group.index)) ser = pd.Series(b,index=group.index) midx = pd.MultiIndex.from_frame(ser.explode().reset_index(name='DATE')[['DATE', 'STORE', 'ADDRESS']]) df = (df.set_index(['DATE', 'STORE', 'ADDRESS']).reindex(midx,fill_value=0).reset_index()) return(df)
但这些方法在百万级大数据集下没有明显性能提升,而仅用透视表能在约2秒完成处理。目前核心瓶颈是创建MultiIndex时的逐行操作(lambda或循环逻辑),耗时占比最高,希望优化该步骤来提升大数据集下的处理速度。
优化方案:利用笛卡尔积生成完整索引
避免逐行生成日期范围,直接通过门店分组和日期范围做笛卡尔积来构建完整的MultiIndex,这是性能提升的关键:
import pandas as pd def fast_fill_missing_dates(df): df['DATE'] = pd.to_datetime(df['DATE']) # 获取所有唯一的门店分组 store_groups = df[['STORE', 'ADDRESS']].drop_duplicates() # 生成目标日期范围 date_range = pd.date_range('2023-11-09', '2023-11-14', freq='D') # 构建笛卡尔积:每个门店分组对应所有日期 full_index = store_groups.assign(key=1).merge( pd.Series(date_range, name='DATE').assign(key=1), on='key' ).drop('key', axis=1) # 设置索引并重新对齐数据 df = df.set_index(['DATE', 'STORE', 'ADDRESS']).reindex( pd.MultiIndex.from_frame(full_index[['DATE', 'STORE', 'ADDRESS']]), fill_value=0 ).reset_index() return df
性能提升原理
- 摒弃
groupby.apply或逐行循环的低效操作,笛卡尔积通过Pandas向量化运算完成,速度远高于逐行生成日期范围 - 用
drop_duplicates提取唯一门店分组,比groupby.nunique更高效,无需额外计算日期数量 - 整个索引构建过程均为向量化操作,完美适配百万级数据集的处理需求
内容的提问来源于stack exchange,提问作者Henrik
相关产品推荐
相关产品推荐

