2017-01-19 145 views
2

我有一個有2列的數據框。我試圖在ID計算的TypeB的%的記錄數如下:Python Pandas GroupBy%計算

公式:(類型B的計數)/(No的組記錄)* 100

Result : 
001 = (2/3) * 100 => 66.66 
002 = (0/2) * 100 => 0 
003 = (1/1) * 100 => 100 

數據幀

ID Type 
001 TypeA 
001 TypeB 
001 TypeB 
002 TypeA 
002 TypeA 
003 TypeB 

所以,到目前爲止,我已經能夠GROUPBY

byID = df.groupby('ID') 

我讀熊貓的交叉表,但似乎無法找出如何通過100接近解決

回答

2

您可以使用groupbysize團體的計數長度第一,unstack0填充NaN重塑然後sum分列TypeB,最後多:

df = df.groupby(['ID','Type']).size().unstack(fill_value=0) 
print (df) 
Type TypeA TypeB 
ID     
1   1  2 
2   2  0 
3   0  1 

df1 = df.TypeB.div(df.sum(axis=1)).mul(100).reset_index(name='percentage') 
print (df1) 
    ID percentage 
0 1 66.666667 
1 2 0.000000 
2 3 100.000000 

對於重塑是可能使用crosstab,但它在更大的數據幀有點slowier:

df = pd.crosstab(df.ID,df.Type) 
print (df) 
Type TypeA TypeB 
ID     
1   1  2 
2   2  0 
3   0  1 

編輯:

可以使用map添加新列:

df1 = df.groupby(['ID','Type']).size().unstack(fill_value=0) 
print (df1) 
Type TypeA TypeB 
ID     
1   1  2 
2   2  0 
3   0  1 

df2 = df1.TypeB.div(df1.sum(axis=1)).mul(100) 
print (df2) 
ID 
1  66.666667 
2  0.000000 
3 100.000000 
dtype: float64 

df['percentage'] = df.ID.map(df2) 
print (df) 
    ID Type percentage 
0 1 TypeA 66.666667 
1 1 TypeB 66.666667 
2 1 TypeB 66.666667 
3 2 TypeA 0.000000 
4 2 TypeA 0.000000 
5 3 TypeB 100.000000 
+0

嗨@jezrael - 請你幫忙解釋一下這個方法。我非常感謝你如何解決這個問題。 – user6083088

+0

更好嗎?重塑後我添加'df'的輸出。 – jezrael

+0

謝謝@jezrael它幫助了我,現在我需要找到一種方法來將這個新的「百分比」列添加到原始數據框中的每個ID。啊!如果只有文檔會解釋你是如何做的。非常感激。 – user6083088

1

使用groupbyvalue_counts(normalize=True)
normalize將總計自動將計數。

df.groupby('ID').Type.value_counts(normalize=True).unstack(fill_value=0).TypeB 

ID 
001 0.666667 
002 0.000000 
003 1.000000 
Name: TypeB, dtype: float64 
+0

謝謝@piRSquared這也行得通。但我只能接受一個答案。 – user6083088