带有均值和计数的条件分组

时间:2017-01-05 11:44:14

标签: python pandas

我想详细说明分组逻辑如下。给定数据框df

df =

    ID  GROUP  DAY  GRADE  TIME_1
    1   AAA    1    5      20
    1   AAA    1    4      19
    1   AAA    1    3      21
    1   BBB    2    1      10
    2   BBB    2    3      13

我需要按IDGRADEGROUPDAY对行进行分组,并计算平均值TIME_1,即组中的行数。另外(这是我的问题),我想检查GRADE是4还是5,那么它应该被分组为正数,并且应该根据它计算平均TIME_1,否则 - 作为负数

结果应该是这个:

result =

    GROUP  DAY  AVG_TIME_1_POSITIVE  AVG_TIME_1_NEGATIVE  QTY_POSITIVE   QTY_NEGATIVE
    AAA    1    19.5                 21                   2              1
    BBB    2    0                    11.5                 0              2

我使用这种方法,但不知道如何通过GRADE指定分组条件:

result = df.groupby(['GROUP','GRADE','DAY']).agg({'TIME_1': 'mean', 
                     'ID': 'count'}).reset_index()

3 个答案:

答案 0 :(得分:2)

一种可能的解决方案是boolean indexing,然后使用concat

mask = df.GRADE.isin([4,5])
result1 = df[mask].groupby(['GROUP','DAY']).agg({'TIME_1': 'mean', 
                     'ID': 'count'}).add_suffix('_POSITIVE')

print (result1)
           TIME_1_POSITIVE  ID_POSITIVE
GROUP DAY                              
AAA   1               19.5            2

result2 = df[~mask].groupby(['GROUP','DAY']).agg({'TIME_1': 'mean', 
                     'ID': 'count'}).add_suffix('_NEGATIVE')

print (result2)
           TIME_1_NEGATIVE  ID_NEGATIVE
GROUP DAY                              
AAA   1               21.0            1
BBB   2               11.5            2

print (pd.concat([result1, result2], axis=1))
           TIME_1_POSITIVE  ID_POSITIVE  TIME_1_NEGATIVE  ID_NEGATIVE
GROUP DAY                                                            
AAA   1               19.5          2.0             21.0            1
BBB   2                NaN          NaN             11.5            2

答案 1 :(得分:2)

您还可以将功能传递给agg类似

的功能
qty_pos = df.groupby(['GROUP','GRADE','DAY']).agg({'GRADE': lambda x: sum(x>3)})
qty_neg = df.groupby(['GROUP','GRADE','DAY']).agg({'GRADE': lambda x: sum(x<=3)})
result['QTY_POSITIVE'] = qty_pos
result['QTY_NEGATIV'] = qty_neg

答案 2 :(得分:0)

对我来说,如果你必须在使用groupby之后手动拆分,应用和组合数据帧,那么它就不是pythonic(我们应该为我们执行split-apply-combine作业)。所以我认为问题是如何为数据集分组制定一个合适的密钥。

输入:

df=df.set_index(['GROUP','DAY', 'GRADE'],drop=False)
key=lambda x: (x[0],x[1], 'positive' if x[2] in [4,5] else 'negative')
df.groupby(key).agg({'TIME_1': 'mean', 'ID': 'count'})

输出:

                   TIME_1   ID
(AAA, 1, negative)  21.0    1
(AAA, 1, positive)  19.5    2
(BBB, 2, negative)  11.5    2