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

时间:2016-11-08 17:29:48

标签: pandas dataframe group-by nested aggregate

我正在尝试按如下方式执行嵌套groupby:

df2

到目前为止一切顺利。现在我尝试将两个结果连接成一个新的DataFrame >>> 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']仅被{{1}}替换,则会失败。

2 个答案:

答案 0 :(得分:1)

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

  1. 只获取每个UiD的第一条记录并将其汇总(汇总) 数量,但也
  2. 总结所有该日期,股票的leg1值 组合(不仅仅是每个UiD的第一个)。是吗?
  3. 无论如何,你想对多个列执行聚合(求和),是的,避免重复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)
    

答案 1 :(得分:0)

如果['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)

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