2017-01-05 35 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