my dataframe:
df = pd.DataFrame({'label':[0,0,1,1,2,2],"gender":['M','F','M','F','M','F'],'count':[100,200,150,210,300,220]})
我试着:
df['percent'] = 100* df['count'] / df.groupby('label')['count'].sum()
但是它只给出了前4行仍然错误的值。
我需要一个列的名称percent
计数的百分比基于标签
输出:
label gender count percent
0 0 M 100 33
1 0 F 200 67
2 1 M 150 41
3 1 F 210 59
4 2 M 300 57
5 2 F 220 43
对于与原始列相同大小的Series的重复聚合值使用GroupBy.transform
,因此可能会分割:
df['percent'] = 100* df['count'] / df.groupby('label')['count'].transform('sum')
print (df)
label gender count percent
0 0 M 100 33.333333
1 0 F 200 66.666667
2 1 M 150 41.666667
3 1 F 210 58.333333
4 2 M 300 57.692308
5 2 F 220 42.307692
详细:
print (df.groupby('label')['count'].transform('sum'))
0 300
1 300
2 360
3 360
4 520
5 520
Name: count, dtype: int64
另一个选项(虽然比transform
更冗长)是使用map
:
mapping = df.label.map(df.groupby("label")["count"].sum())
df.assign(percent=df["count"].mul(100).div(mapping))
label gender count percent
0 0 M 100 33.333333
1 0 F 200 66.666667
2 1 M 150 41.666667
3 1 F 210 58.333333
4 2 M 300 57.692308
5 2 F 220 42.307692
还有一个选择是使用set_index
/reset_index
的技巧。
d = df.set_index(['label', 'gender'])
d.mul(100).div(d.sum(level=0)).reset_index()
label gender count
0 0 M 33.333333
1 0 F 66.666667
2 1 M 41.666667
3 1 F 58.333333
4 2 M 57.692308
5 2 F 42.307692
对于字符串表示,您可以在这里使用python的mini string language
。
d = df.set_index(['label', 'gender'])
d.div(d.sum(level=0))['count'].map("{:%}".format).reset_index()
label gender count
0 0 M 33.333333%
1 0 F 66.666667%
2 1 M 41.666667%
3 1 F 58.333333%
4 2 M 57.692308%
5 2 F 42.307692%