如何在Pandas DataFrame中按维度组合补全缺失的整行数据?
Pandas生成全维度组合DataFrame实现方案
问题背景
原始DataFrame如下:
import pandas as pd df_ref = pd.DataFrame({ 'district':['A Nzo DM','A Nzo DM','uMgungundlovu DM','uMgungundlovu DM','uMgungundlovu DM','uMgungundlovu DM','uMgungundlovu DM'], 'visit_date':['2021-07-31','2021-07-31','2021-07-31','2021-07-31','2021-08-31','2021-08-31','2021-08-31'], 'province':['EC','EC','NC','NC','NC','NC','NC'], 'age_group':['35-49','50-59','18-34','35-49','18-34','35-49','Unidentified'], 'sex':['Male','Female','Female','Male','Female','Male','Female'], 'vaccinations':[1,5,6,8,9,10,14] })
需要生成满足以下要求的DataFrame:
- 每个
district对应所有已存在的visit_date - 每个
sex(Male、Female)匹配所有指定年龄组:18-34、35-49、50-59、60+、Unidentified - 保留
district与province的对应关系
实现步骤
1. 定义固定维度集合
先明确需要覆盖的年龄组和性别选项:
# 指定所有需要的年龄组 required_age_groups = ['18-34', '35-49', '50-59', '60+', 'Unidentified'] # 指定需要的性别 required_sexes = ['Male', 'Female']
2. 提取基础维度组合
从原始数据中获取district、visit_date、province的唯一组合(确保每个地区+日期对应正确省份):
# 获取唯一的地区-日期-省份组合 base_combinations = df_ref[['district', 'visit_date', 'province']].drop_duplicates()
3. 生成全量笛卡尔积
用pd.MultiIndex.from_product生成年龄组和性别的所有组合,再与基础组合拼接:
# 生成年龄组和性别的笛卡尔积 age_sex_product = pd.MultiIndex.from_product( [required_age_groups, required_sexes], names=['age_group', 'sex'] ).to_frame(index=False) # 将基础组合与年龄性别组合进行笛卡尔积拼接 df_full = base_combinations.merge(age_sex_product, how='cross')
4. (可选)填充疫苗接种数据
如果需要将原始数据中的vaccinations值填充到对应组合中,缺失的补0:
# 关联原始数据的接种数,缺失值填充为0 df_full = df_full.merge( df_ref[['district', 'visit_date', 'age_group', 'sex', 'vaccinations']], on=['district', 'visit_date', 'age_group', 'sex'], how='left' ).fillna({'vaccinations': 0})
最终结果
执行上述代码后,df_full即为所需的全维度组合DataFrame,结构与示例输出一致。
完整代码
import pandas as pd # 原始数据 df_ref = pd.DataFrame({ 'district':['A Nzo DM','A Nzo DM','uMgungundlovu DM','uMgungundlovu DM','uMgungundlovu DM','uMgungundlovu DM','uMgungundlovu DM'], 'visit_date':['2021-07-31','2021-07-31','2021-07-31','2021-07-31','2021-08-31','2021-08-31','2021-08-31'], 'province':['EC','EC','NC','NC','NC','NC','NC'], 'age_group':['35-49','50-59','18-34','35-49','18-34','35-49','Unidentified'], 'sex':['Male','Female','Female','Male','Female','Male','Female'], 'vaccinations':[1,5,6,8,9,10,14] }) # 1. 定义固定维度 required_age_groups = ['18-34', '35-49', '50-59', '60+', 'Unidentified'] required_sexes = ['Male', 'Female'] # 2. 获取基础组合 base_combinations = df_ref[['district', 'visit_date', 'province']].drop_duplicates() # 3. 生成年龄性别笛卡尔积 age_sex_product = pd.MultiIndex.from_product( [required_age_groups, required_sexes], names=['age_group', 'sex'] ).to_frame(index=False) # 4. 拼接全量组合 df_full = base_combinations.merge(age_sex_product, how='cross') # 可选:填充接种数据 df_full = df_full.merge( df_ref[['district', 'visit_date', 'age_group', 'sex', 'vaccinations']], on=['district', 'visit_date', 'age_group', 'sex'], how='left' ).fillna({'vaccinations': 0}) # 查看结果 print(df_full)
内容的提问来源于stack exchange,提问作者Mazil_tov998
相关产品推荐
相关产品推荐

