【问题标题】:reindex multi level index with missing categories重新索引缺少类别的多级索引
【发布时间】:2021-12-03 15:17:09
【问题描述】:

我有一个带有两个索引的数据框,groupclass。我有一本字典,其中包含需要添加到这两个索引中的其他级别。具体来说,我想将 E 添加到 group 索引中。而且我想确保每个 group 中的所有 g1、g2 和 g3 都存在于 class 索引中(因此将 g3 添加到组 A,将 g1 添加到组 B,g2 和g3 到 C 组,g1 和 g3 到 D 组和 g1、g2 和 g3 到 E 组。我想在适当的地方用零填充总列

原始数据框在这里

df = pd.DataFrame(data={'group' : ['A','A','B','B','C','D'],
                        'class': ['g1','g2','g2','g3','g1','g2'],
                        'total' : [3,14,12,11,21,9]})

包含所有必需类别的字典(和映射的 df)在这里

dic = {'group':['A','B','C','D','E'],
       'class' : ['g1','g2','g3']}

预期的输出就在这里

expectedOutput = pd.DataFrame(data={'group' : ['A','A','A','B','B','B','C','C','C','D','D','D','E','E','E'],
                        'class': ['g1','g2', 'g3','g1','g2', 'g3','g1','g2', 'g3','g1','g2', 'g3','g1','g2', 'g3'],
                        'total' : [3,14,0, 0,12,11,21,0,0,0,9,0, 0,0,0]})

我在重新编制索引时无法维护重复的值,但我需要将它们全部保留。欢迎大家多多指教,万分感谢

【问题讨论】:

    标签: python pandas dataframe multi-index reindex


    【解决方案1】:

    您可以使用漂亮的pyjanitor 模块及其complete 方法:

    # pip install pyjanitor
    import janitor as jn 
    (df.complete({'group': list(df['group'].unique())+['D', 'E']}, 'class')
       .fillna(0, downcast='infer')
    )
    

    输出:

       group class  total
    0      A    g1      3
    1      A    g2     14
    2      A    g3      0
    3      B    g1      0
    4      B    g2     12
    5      B    g3     11
    6      C    g1     21
    7      C    g2      0
    8      C    g3      0
    9      D    g1      0
    10     D    g2      9
    11     D    g3      0
    12     E    g1      0
    13     E    g2      0
    14     E    g3      0
    

    【讨论】:

    • 我认为如果您按原样使用dic,您仍然会得到相同的结果:df.complete(dic).fillna(0, downcast='infer')
    • @sammywemmy 有一个额外的值要添加 (E)。顺便说一句,看,现在我开始使用 pyjanitor ;)
    【解决方案2】:

    使用MultiIndex 的解决方案 - 由MultiIndex.from_product 使用DataFrame.reindexdict 创建:

    dic = {'group':['A','B','C','D','E'],
           'class' : ['g1','g2','g3']}
    
    mux = pd.MultiIndex.from_product(dic.values(), names=dic)
    
    df = df.set_index(list(dic)).reindex(mux, fill_value=0).reset_index()
    print (df)
       group class  total
    0      A    g1      3
    1      A    g2     14
    2      A    g3      0
    3      B    g1      0
    4      B    g2     12
    5      B    g3     11
    6      C    g1     21
    7      C    g2      0
    8      C    g3      0
    9      D    g1      0
    10     D    g2      9
    11     D    g3      0
    12     E    g1      0
    13     E    g2      0
    14     E    g3      0
    

    或者由DataFrame创建的itertools.product左连接:

    from  itertools import product
    
    dicDf = pd.DataFrame(product(*dic.values()), columns=dic)
    
    df = dicDf.merge(df, how='left').fillna({'total':0})
    print (df)
       group class  total
    0      A    g1    3.0
    1      A    g2   14.0
    2      A    g3    0.0
    3      B    g1    0.0
    4      B    g2   12.0
    5      B    g3   11.0
    6      C    g1   21.0
    7      C    g2    0.0
    8      C    g3    0.0
    9      D    g1    0.0
    10     D    g2    9.0
    11     D    g3    0.0
    12     E    g1    0.0
    13     E    g2    0.0
    14     E    g3    0.0
    

    【讨论】:

    • @ScottBoston - 谢谢,解压再打包,太复杂了。
    • 哦,哇,答案很快,谢谢!我也可以看到我的 dicDf 实际上并没有工作,因为它在“组”中删除项目,其中“类”中没有项目与行级别匹配 *我将更新它
    猜你喜欢
    • 2013-12-04
    • 2018-08-24
    • 2016-07-12
    • 2015-08-31
    • 1970-01-01
    • 2020-05-19
    • 2023-03-10
    • 2019-01-22
    • 2019-11-19
    相关资源
    最近更新 更多