2017-01-19 19 views
2

私は2列のデータフレームを持っています。私は次のようにIDのレコード数にタイプBの%を計算しようとしている:Python Pandas GroupBy%の計算

式:(タイプBのカウント)/(グループ内のレコードはありません)* 100

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

DATAFRAME

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

だから、これまで私は、私はパンダのクロス集計を読んでいた

byID = df.groupby('ID') 

をGROUPBYすることができましたが、それに見えることはできません100で最後の複数

答えて

2

あなたは0NaNを充填してunstackによって再形成した後、sumで列TypeBを分割、最初のグループのカウント長さsizegroupbyを使用することができるソリューションを、アプローチする方法を見つけ出す:

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 

EDIT:

あなたは新しい列を追加するための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

使用groupby
normalizevalue_counts(normalize=True)と、自動的に合計でカウントを分割します。

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これも動作します。しかし、私は1つの答えしか受け入れることができません。 – user6083088

関連する問題