【问题标题】:Groupby sum, index vs. column resultsGroupby 总和,索引与列结果
【发布时间】:2019-10-04 14:04:31
【问题描述】:

对于以下数据框:

df = pd.DataFrame({'group':['a','a','b','b'], 'data':[5,10,100,30]},columns=['group', 'data']) 
print(df)

  group  data
0     a     5
1     a    10
2     b   100
3     b    30

按列分组时,添加并新建一列,结果为:

df['new'] = df.groupby('group')['data'].sum() 
print(df)

  group  data  new
0     a     5  NaN
1     a    10  NaN
2     b   100  NaN
3     b    30  NaN

但是,如果我们将 df 重置为原始数据并将 group 列移动到索引,

df.set_index('group', inplace=True)
print(df)

       data
group      
a         5
a        10
b       100
b        30

然后分组求和,得到:

df['new'] = df.groupby('group')['data'].sum() 
print(df)

       data  new
group           
a         5   15
a        10   15
b       100  130
b        30  130

为什么列组不设置新列的值,而索引分组却设置了新列的值?

【问题讨论】:

    标签: python pandas indexing group-by


    【解决方案1】:

    这里更好的是使用GroupBy.transform 来返回与原始DataFrame 相同大小的系列,因此在分配后所有工作正常:

    df['new'] = df.groupby('group')['data'].transform('sum')
    

    因为如果分配新的系列值是按索引值对齐的。如果索引不同,获取NaNs:

    print (df.groupby('group')['data'].sum())
    group
    a     15
    b    130
    Name: data, dtype: int64
    

    不同的索引值 - 获取 NaN:

    print (df.groupby('group')['data'].sum().index)
    Index(['a', 'b'], dtype='object', name='group')
    
    print (df.index)
    RangeIndex(start=0, stop=4, step=1)
    

    df.set_index('group', inplace=True)
    
    print (df.groupby('group')['data'].sum())
    group
    a     15
    b    130
    Name: data, dtype: int64
    

    索引可以对齐,因为值匹配:

    print (df.groupby('group')['data'].sum().index)
    Index(['a', 'b'], dtype='object', name='group')
    
    print (df.index)
    Index(['a', 'a', 'b', 'b'], dtype='object', name='group')
    

    【讨论】:

      【解决方案2】:

      你没有得到你想要的,因为当使用df.groupby('group')['data'].sum()时,这会返回一个以group为索引的聚合结果:

      group
      a     15
      b    130
      Name: data, dtype: int64
      

      显然索引没有对齐。

      如果你想让它工作,你必须使用transform,它返回一个带有转换后的值的系列,与 self 具有相同的轴长度

      df['new'] = df.groupby('group')['data'].transform('sum')
      
         group  data  new
      0     a     5   15
      1     a    10   15
      2     b   100  130
      3     b    30  130
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-16
        相关资源
        最近更新 更多