2017-01-05 38 views
3

我想详细说明如下的分组逻辑。鉴于数据帧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() 

回答

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 
+0

没有你的数据很难回答的问题。是'print(type(mask))'''Series'? – jezrael

2

您c一个也传递功能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 
0

对我来说,这不是Python的,如果你要手动拆分,应用和您使用GROUPBY后合并数据帧(这是应该做的分裂适用─为我们结合工作)。所以我认为问题在于如何为数据框分组制定合适的密钥。

输入:

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