如何设置MultiIndex DataFrame索引以保留所有无值的索引项
问题解决方案
你遇到的截断问题核心原因有两点:
groupby方法默认开启dropna=True,会自动丢弃包含空值的分组,若某个索引层级全为空/无有效数据,整个层级会在分组结果中被剔除- 你从分组后的
grouped_df.index.levels取索引值,分组结果已经裁剪过索引,自然无法拿到完整的层级取值
修复方案
方案1:预先定义所有索引层级的合法取值(最稳定,推荐)
如果业务中四个索引层级的所有可能取值是固定的,直接手动定义取值列表,完全不受源数据情况影响:
import pandas as pd index_levels = ['Channel', 'Duration', 'Designation', 'Manufacturing Class'] # 按顺序填写每个层级的所有合法取值,根据实际业务调整即可 level_all_values = [ ['线上', '线下', '分销'], # Channel的所有可能值 ['月卡', '季卡', '年卡'], # Duration的所有可能值 ['普通用户', '会员', 'VIP'], # Designation的所有可能值 ['自产', '代加工', '外购'] # Manufacturing Class的所有可能值 ] # 分组时关闭dropna,保留空值分组避免层级丢失 grouped_df = df.groupby(by=index_levels, dropna=False)[['Total Purchases', 'Sales', 'Cost']].sum() # 用预先定义的全量取值生成完整MultiIndex full_multi_index = pd.MultiIndex.from_product(level_all_values, names=index_levels) # 重索引补0 grouped_df = grouped_df.reindex(full_multi_index, fill_value=0)
方案2:从原始DataFrame取全量索引值
如果索引取值不固定,需要随源数据动态更新,就从原始df而非分组结果中取每个层级的唯一值:
index_levels = ['Channel', 'Duration', 'Designation', 'Manufacturing Class'] # 从原始df提取每个索引列的所有唯一值,可根据需要保留/删除dropna()来过滤空值 level_all_values = [df[col].dropna().unique() for col in index_levels] grouped_df = df.groupby(by=index_levels, dropna=False)[['Total Purchases', 'Sales', 'Cost']].sum() full_multi_index = pd.MultiIndex.from_product(level_all_values, names=index_levels) grouped_df = grouped_df.reindex(full_multi_index, fill_value=0)
提示:如果使用pandas 1.1.0以下版本,不支持
groupby的dropna参数,可以提前将索引列的空值替换为业务中不会出现的占位符(比如__未知__),分组完成后如果不需要可以再过滤掉对应索引项。
内容的提问来源于stack exchange,提问作者user16537374
相关产品推荐
相关产品推荐

