【问题标题】:Pandas: Add an empty row after every index in a MultiIndex dataframePandas:在 MultiIndex 数据框中的每个索引之后添加一个空行
【发布时间】:2021-04-17 03:19:07
【问题描述】:

考虑下面df

              IA1  IA2  IA3
Name Subject               
Abc  DS        45   43   34
     DMS       43   23   45
     ADA       32   46   36
Bcd  BA        45   35   37
     EAD       23   45   12
     DS        23   35   43
Cdf  EAD       34   33   23
     ADA       12   34   25

如何在每个Name 索引后添加一个空行?

预期输出:

              IA1  IA2  IA3
Name Subject               
Abc  DS        45   43   34
     DMS       43   23   45
     ADA       32   46   36

Bcd  BA        45   35   37
     EAD       23   45   12
     DS        23   35   43

Cdf  EAD       34   33   23
     ADA       12   34   25
     

【问题讨论】:

    标签: python python-3.x pandas dataframe multi-index


    【解决方案1】:
    # reset index 
    dfn = df.reset_index()
    # find the border idx of 'Name', [2, 5, 7]
    idx_list = dfn.drop_duplicates('Name', keep='last').index
    # use the border idx, create an empty df, and append to the origin df, then sort the index
    df_append = pd.DataFrame('', index = idx_list, columns = dfn.columns)
    obj = dfn.append(df_append).sort_index().set_index(['Name', 'Subject'])
    print(obj)
    
                 IA1 IA2 IA3
    Name Subject            
    Abc  DS       45  43  34
         DMS      43  23  45
         ADA      32  46  36
                            
    Bcd  BA       45  35  37
         EAD      23  45  12
         DS       23  35  43
                            
    Cdf  EAD      34  33  23
         ADA      12  34  25
    

    【讨论】:

      【解决方案2】:

      在使用 pd.MultiIndex.from_productIndex.union 之后使用 df.reindexfill_value 作为 '' 添加另一种方式,然后排序。

      idx = df.index.union(pd.MultiIndex.from_product((df.index.levels[0],[''])),sort=False)
      out = df.reindex(sorted(idx,key=lambda x: x[0]),fill_value='')
      

      print(out)
      
                   IA1 IA2 IA3
      Name Subject            
      Abc  DS       45  43  34
           DMS      43  23  45
           ADA      32  46  36
                              
      Bcd  BA       45  35  37
           EAD      23  45  12
           DS       23  35  43
                              
      Cdf  EAD      34  33  23
           ADA      12  34  25
       
      

      我们在使用Index.union 时使用sort=False 索引因此保留顺序,然后在第一个元素上使用sorted 返回:

      sorted(idx,key=lambda x:x[0])
      
      [('Abc', 'DS'),
       ('Abc', 'DMS'),
       ('Abc', 'ADA'),
       ('Abc', ''),
       ('Bcd', 'BA'),
       ('Bcd', 'EAD'),
       ('Bcd', 'DS'),
       ('Bcd', ''),
       ('Cdf', 'EAD'),
       ('Cdf', 'ADA'),
       ('Cdf', '')]
      

      【讨论】:

        【解决方案3】:

        使用自定义函数在GroupBy.apply中添加空行:

        def f(x):
            x.loc[('', ''), :] = ''
            return x
        

        或者:

        def f(x):
            return x.append(pd.DataFrame('', columns=df.columns, index=[(x.name, '')]))
        

        df = df.groupby(level=0, group_keys=False).apply(f)
        print (df)
                     IA1 IA2 IA3
        Name Subject            
        Abc  DS       45  43  34
             DMS      43  23  45
             ADA      32  46  36
                                
        Bcd  BA       45  35  37
             EAD      23  45  12
             DS       23  35  43
                                
        Cdf  EAD      34  33  23
             ADA      12  34  25
                                
        

        【讨论】:

          猜你喜欢
          • 2015-12-13
          • 2015-09-05
          • 2021-03-30
          • 2018-04-19
          • 1970-01-01
          • 2013-01-02
          • 2022-01-13
          • 2013-10-16
          • 2020-09-30
          相关资源
          最近更新 更多