在DataFrame中嵌套groupby并聚合多个列

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在DataFrame中嵌套groupby并聚合多个列相关的知识,希望对你有一定的参考价值。

我试图做嵌套groupby如下:

>>> df1 = pd.DataFrame({'Date': {0: '2016-10-11', 1: '2016-10-11', 2: '2016-10-11', 3: '2016-10-11', 4: '2016-10-11',5: '2016-10-12'}, 'Stock': {0: 'ABC', 1: 'ABC', 2: 'ABC', 3: 'ABC', 4: 'ABC', 5: 'XYZ'}, 'Quantity': {0: 60,1: 50, 2: 40, 3: 30, 4: 20, 5: 10}, 'UiD':{0:1,1:1,2:1,3:2,4:2,5:3}, 'StartTime': {0: '08:00:00.241', 1: '08:00:00.243', 2: '12:34:23.563', 3: '08:14.05.908', 4: '18:54:50.100', 5: '10:08:36.657'}, 'Sign':{0:1,1:1,2:0,3:-1,4:0,5:-1}, 'leg1':{0:2,1:2,2:4,3:5,4:7,5:8}})
>>> df1
         Date  Quantity  Sign     StartTime Stock  UiD  leg1
0  2016-10-11        60     1  08:00:00.241   ABC    1     2
1  2016-10-11        50     1  08:00:00.243   ABC    1     2
2  2016-10-11        40     0  12:34:23.563   ABC    1     4
3  2016-10-11        30    -1  08:14.05.908   ABC    2     5
4  2016-10-11        20     0  18:54:50.100   ABC    2     7
5  2016-10-12        10    -1  10:08:36.657   XYZ    3     8
>>> dfg1=df1.groupby(['Date','Stock'])
>>> dfg1.apply(lambda x:x.groupby('UiD').first()).groupby(['Date','Stock']).apply(lambda x:np.sum(x['Quantity']))
Date        Stock
2016-10-11  ABC      90
2016-10-12  XYZ      10
dtype: int64
>>>
>>> dfg1['leg1'].sum()
Date        Stock
2016-10-11  ABC      20
2016-10-12  XYZ       8
Name: leg1, dtype: int64

到现在为止还挺好。现在我尝试将两个结果连接成一个新的DataFrame df2,如下所示:

>>> df2 = pd.concat([dfg1['leg1'].sum(), dfg1.apply(lambda x:x.groupby('UiD').first()).groupby(['Date','Stock']).apply(lambda x:np.sum(x['Quantity']))],axis=1)
                   0   1
Date       Stock        
2016-10-11 ABC    20  90
2016-10-12 XYZ     8  10
>>>

我想知道是否有更好的方法来重写下一行,以避免重复groupby(['Date','Stock'])

dfg1.apply(lambda x:x.groupby('UiD').first()).groupby(['Date','Stock']).apply(lambda x:np.sum(x['Quantity']))

如果['Date','Stock']包含'UiD'作为关键之一或['Date','Stock']['UiD']替换,这也失败了。

答案

请重申您的问题以便更清楚。你想要groupby(['Date','Stock']),然后:

  1. 只取每个UiD的第一个记录并总和(汇总)其数量,但也
  2. 汇总该日期,股票组合的所有leg1值(不仅仅是每个UiD的第一个)。是对的吗?

无论如何你想在多个列上执行聚合(求和),是的,避免重复groupby(['Date','Stock'])的方法是保留一个数据帧,而不是试图将两个数据帧拼接在一起集合运营。类似下面的内容(一旦你确认这是你想要的,我会解决它):

def filter_first_UiD(g):
    #return g.groupby('UiD').first().agg(np.sum)
    return g.groupby('UiD').first().agg({'Quantity':'sum', 'leg1':'sum'})

df1.groupby(['Date','Stock']).apply(filter_first_UiD)
另一答案

如果['Date','Stock']包含'UiD'作为其中一个键或['Date','Stock']['UiD']替换,我处理避免groupby失败的最后一个场景的方式如下:

>>> df2 = pd.concat([dfg1['leg1'].sum(), dfg1[].first() if 'UiD' in `['Date','Stock']` else dfg1.apply(lambda x:x.groupby('UiD').first()).groupby(['Date','Stock']).apply(lambda x:np.sum(x['Quantity']))],axis=1)

但更优雅的解决方案仍是一个悬而未决的问题

以上是关于在DataFrame中嵌套groupby并聚合多个列的主要内容,如果未能解决你的问题,请参考以下文章

pandas使用groupby函数基于多个分组变量(多变量分组)对dataframe数据进行分组使用mean函数计算所有分组下数据变量的聚合平均值

pandas使用groupby函数基于多个分组变量(多变量分组)对dataframe数据进行分组使用mean函数计算所有分组下数据变量的聚合平均值

pandas使用groupby函数基于多个分组变量(多变量分组)对dataframe数据进行分组使用sum函数计算所有分组下数据变量的聚合加和值

Dataframe GroupBy 在包含模式的列上聚合

Spark Dataframe GroupBy 和计算复杂聚合函数

pandas聚合和分组运算之groupby