代码之家  ›  专栏  ›  技术社区  ›  rahlf23

在GroupBy上执行Sum后保留输出中的列

  •  4
  • rahlf23  · 技术社区  · 6 年前

    给出一个样本 df 以下内容:

    df = pd.DataFrame([['William', 1, 0, 'T', 0, 1],['James', 0, 1, 'R', 1, 1],['James', 1, 0, 'S', 0, 1],['Dean', 1, 0, 'R', 1, 0],['William', 0, 1, 'S', 0, 0],['James', 0, 0, 'S', 0, 1]],columns=['Name','x1','x2','x3','x4','x5']) 
    
          Name  x1  x2 x3  x4  x5
    0  William   1   0  T   0   1
    1    James   0   1  R   1   1
    2    James   1   0  S   0   1
    3     Dean   1   0  R   1   0
    4  William   0   1  S   0   0
    5    James   0   0  S   0   1
    

    我以前问过一个问题,如何对其应用各种过滤器 测向 并将应用于每个组对象的一系列函数的结果从 groupby ,我得出了以下解决方案:

    variables = {'x1': 'sum','x2': 'sum','x4': 'sum','x5': 'sum'}
    filters = {'Option1': df['x3']=='S', 'Option2': df['x3']=='R', 'Option3': (df['x2']==1) | (df['x4']==1) | (df['x5']==1), 'Option4': df['x2']==1, 'Option5': df['x2']==0, 'Option6': df['x5']==1}
    
    out = {key: df[f].groupby('Name').agg(variables) for key, f in filters.items()}
    
    out = pd.concat(results)
    

    在连接了结果之后,我只剩下以下内容:

                     x1  x2  x4  x5
            Name                   
    Option1 James     1   0   0   2
            William   0   1   0   0
    Option2 Dean      1   0   1   0
            James     0   1   1   1
    Option3 Dean      1   0   1   0
            James     1   1   1   3
            William   1   1   0   1
    Option4 James     0   1   1   1
            William   0   1   0   0
    Option5 Dean      1   0   1   0
            James     1   0   0   2
            William   1   0   0   1
    Option6 James     1   1   1   3
            William   1   0   0   1
    

    我想再来一次 groupby('Name') ,这给了我:

                  x1  x2  x4  x5
            Name                
    Option2 Dean   1   0   1   0
    Option3 Dean   1   0   1   0
    Option5 Dean   1   0   1   0 
    
    
                   x1  x2  x4  x5
            Name                 
    Option1 James   1   0   0   2
    Option2 James   0   1   1   1
    Option3 James   1   1   1   3
    Option4 James   0   1   1   1
    Option5 James   1   0   0   2
    Option6 James   1   1   1   3 
    
    
                     x1  x2  x4  x5
            Name                   
    Option1 William   0   1   0   0
    Option3 William   1   1   0   1
    Option4 William   0   1   0   0
    Option5 William   1   0   0   1
    Option6 William   1   0   0   1 
    

    但是,我有列(或行,取决于您如何看待它),这些列(或行)被从结果(例如过滤器)中删除 df['x3']=='S' 将离开 Name 没有实例的列 'Dean' )。我觉得我离这里很近,但这是我想要的输出(名称的排序不相关):

                      x1  x2  x4  x5
    Name                   
    James   Option1   1   0   0   2
            Option2   0   1   1   1
            Option3   1   1   1   3
            Option4   0   1   1   1
            Option5   1   0   0   2
            Option6   1   1   1   3
    Dean    Option1   0   0   0   0
            Option2   1   0   1   0
            Option3   1   0   1   0
            Option4   0   0   0   0
            Option5   1   0   1   0
            Option6   0   0   0   0
    William Option1   0   1   0   0
            Option2   0   0   0   0
            Option3   1   1   0   1
            Option4   0   1   0   0
            Option5   1   0   0   1
            Option6   1   0   0   1
    

    谢谢你的指点。

    1 回复  |  直到 6 年前
        1
  •  4
  •   ALollz    6 年前

    out 数据帧和交换索引级别。从串联的结果开始:

    from itertools import product
    
    # Swap the index levels
    out = out.swaplevel(0,1)
    
    # Form the product of the two index levels
    ids = list(product(out.index.get_level_values(0).unique(), 
                       out.index.get_level_values(1).unique()))
    
    # Reindex out, filling missing with 0 and sorting the index
    out = out.reindex(ids).fillna(0).sort_index().astype('int')
    

    外面的 现在是:

                     x1  x2  x4  x5
    Name                           
    Dean    Option1   0   0   0   0
            Option2   1   0   1   0
            Option3   1   0   1   0
            Option4   0   0   0   0
            Option5   1   0   1   0
            Option6   0   0   0   0
    James   Option1   1   0   0   2
            Option2   0   1   1   1
            Option3   1   1   1   3
            Option4   0   1   1   1
            Option5   1   0   0   2
            Option6   1   1   1   3
    William Option1   0   1   0   0
            Option2   0   0   0   0
            Option3   1   1   0   1
            Option4   0   1   0   0
            Option5   1   0   0   1
            Option6   1   0   0   1