2016-01-24 108 views
2

所以我們可以說我有一些數據如下:熊貓:聚合不同的基於組

patient_id lab_type value 
1   food  10 
1   food  8 
2   food  3 
2   food  5 
1   shot  4 
1   shot  10 
2   shot  2 
2   shot  4 

然後我會組的東西,如groupby(['patient_id', 'lab_type'])

在那之後,我想聚集在value但每個lab_type都不相同。在food我想使用meanshot進行彙總,我想使用sum進行彙總。

最終的數據應該是這樣的:

patient_id lab_type value 
    1   food  9 (10 + 8/2) 
    2   food  4 (3 + 5/2) 
    1   shot  14 (10 + 4) 
    2   shot  6 (2 + 4) 
+0

只寫一個函數檢查其輸入的'lab_type',並根據它的內容做不同的事情,然後''應用'那個函數給groupby。 – BrenBarn

回答

1

關於食物我想聚合使用均值和在射擊我想彙總使用總和。

只需使用.apply並傳遞一個自定義函數:

def calc(g): 
    if g.iloc[0].lab_type == 'shot': 
     return sum(g.value) 
    else: 
     return np.mean(g.value) 
result = df.groupby(['patient_id', 'lab_type']).apply(calc) 

這裏calc接收作爲在Panda's split-apply-combine所示的每個數據幀組。因此,你得到你想要的東西:

patient_id lab_type 
1   food   9 
      shot  14 
2   food   4 
      shot   6 
dtype: float64 
+0

你的答案似乎是最簡潔的,但是,你能解釋一下在這種情況下g是指什麼,你需要返回什麼? – adrian

+0

'calc'每個組被調用一次,'g'是指組中的數據(實際上是一個DataFrame)。返回的值是您應用的任何操作的結果,在這種情況下,它是計算的統計量。本質上,熊貓自動連接所有結果。 – miraculixx

0

答案在this post看起來很有希望。從這開始,我想出了下面的代碼,它應該適合你。

TESTDATA:

data = [{"A" : 1, "B" : "food", "C" : 10}, 
{"A" : 1, "B" : "food", "C" : 8}, 
{"A" : 2, "B" : "food", "C" : 3}, 
{"A" : 2, "B" : "food", "C" : 5}, 
{"A" : 1, "B" : "shot", "C" : 4}, 
{"A" : 1, "B" : "shot", "C" : 10}, 
{"A" : 2, "B" : "shot", "C" : 2}, 
{"A" : 2, "B" : "shot", "C" : 4}]  
df = pd.DataFrame(data) 

實際代碼:

res = df.groupby(['A', 'B']).apply(
    lambda x: pd.Series(
    {"value" : x.C.mean() if x.iloc[0].B == "food" else x.C.sum()} 
) 
) 

這導致

 value 
A B   
1 food  9 
    shot  14 
2 food  4 
    shot  6 
0

P是你的數據幀。

P[P.lab_type =="food"].groupby(['patient_id']).aggregate(np.avg) 

和類似地對於shot組和concatenate結果。

1

我嘗試修改john答案:

您可以使用meansum然後concatreset_index

print df 
    patient_id lab_type value 
0   1  food  10 
1   1  food  8 
2   2  food  3 
3   2  food  5 
4   1  shot  4 
5   1  shot  10 
6   2  shot  2 
7   2  shot  4 


df1 = df[df.lab_type =="food"].groupby(['patient_id']).mean() 
df1['lab_type'] = 'food' 
print df1 
      value lab_type 
patient_id     
1    9  food 
2    4  food 

df2 = df[df.lab_type =="shot"].groupby(['patient_id']).sum() 
df2['lab_type'] = 'shot' 
print df2 
      value lab_type 
patient_id     
1    14  shot 
2    6  shot 

print pd.concat([df1, df2]).reset_index() 
    patient_id value lab_type 
0   1  9  food 
1   2  4  food 
2   1  14  shot 
3   2  6  shot 
+0

這是一個可靠的答案,但與米拉的答案相比略顯冗長。 – adrian

+0

是的,你是對的。 – jezrael