如何使用Pandas填充数据集中缺失的部门-日期行并补零
Pandas补全部门-日期的缺失记录方法
嗨,这个需求在Pandas里其实有好几种简洁的实现方式,我来给你一步步讲清楚:
首先先准备好你的示例数据,方便我们测试:
import pandas as pd # 原始数据集 data = { 'Dept': ['dept1', 'dept1', 'dept2', 'dept3', 'dept2', 'dept3'], 'Date': ['2020-01-01', '2020-01-03', '2020-01-03', '2020-01-03', '2020-01-04', '2020-01-04'], 'Number': [12, 34, 56, 78, 11, 12] } df = pd.DataFrame(data)
方法一:MultiIndex + reindex(高效直接)
这种方法的核心是生成部门和日期的笛卡尔积作为索引,再对齐原始数据填充缺失值:
# 提取所有唯一的部门和日期 unique_depts = df['Dept'].unique() unique_dates = df['Date'].unique() # 创建部门与日期的笛卡尔积索引(MultiIndex) full_index = pd.MultiIndex.from_product( [unique_depts, unique_dates], names=['Dept', 'Date'] ) # 重新索引并填充缺失值为0,最后重置索引变回普通列 df_complete = df.set_index(['Dept', 'Date'])\ .reindex(full_index, fill_value=0)\ .reset_index()
方法二:透视表(pivot_table)+ 宽表转长表(melt)
如果你习惯用透视表的思路,这种方法也很直观:
# 生成透视表,自动补全缺失的部门-日期对,用0填充空值 pivot_df = df.pivot_table( index='Date', columns='Dept', values='Number', fill_value=0 ) # 把宽格式的透视表转回长格式,和原始数据结构一致 df_complete = pivot_df.reset_index()\ .melt(id_vars='Date', var_name='Dept', value_name='Number') # 可选:按日期和部门排序,让结果更规整 df_complete = df_complete.sort_values(['Date', 'Dept']).reset_index(drop=True)
方法三:笛卡尔积数据框 + 左连接(merge)
这种方法逻辑最直白,先生成所有可能的部门-日期组合,再和原始数据做左连接:
# 生成所有部门-日期的笛卡尔积组合 full_combinations = pd.DataFrame( [(dept, date) for dept in unique_depts for date in unique_dates], columns=['Dept', 'Date'] ) # 左连接原始数据,缺失的Number列填充为0 df_complete = pd.merge( full_combinations, df, on=['Dept', 'Date'], how='left' ).fillna({'Number': 0}) # 可选:排序整理结果 df_complete = df_complete.sort_values(['Date', 'Dept']).reset_index(drop=True)
这三种方法都能实现你要的效果,你可以根据自己的习惯和数据规模选择——reindex的方式在大数据集上效率更高,pivot_table适合熟悉报表逻辑的用户,merge的方式最容易理解。
内容的提问来源于stack exchange,提问作者Niuya
相关产品推荐
相关产品推荐

