假设我在一个我想要使用的pandas数据框中有一些数据。
>>> df = pd.DataFrame([['a',10,5],['a',12,6],['b',4,2],['b',5,10]],
... columns=['id','val','val2']))
所以数据框看起来像这样:
>>> df
id val val2
0 a 10 5
1 a 12 6
2 b 4 2
3 b 5 10
我想要实现的是一个数据框,其中id
值为列名,val
和val2
为行名,其中值应按以下方式组成:
根据id
构建值列的平均值,留下类似
id mean-val mean-val2
a 11 5.5
b 4.5 6
根据mean-val
(例如mean-val2
)计算id
和11 / (11+5.5) * 100 = 66.67
对两个值之和的百分比,呈现
id perc-val perc-val2
a 66.67 33.33
b 42.86 57.14
最终的数据框应如下所示:
>>> new_df
a b
val 66.67 42.86
val2 33.33 57.14
我对大熊猫很缺乏经验,所以我花了一段时间才得到一种不满意的方法。
>>> idx = ['val','val2']
>>> lst = [df.groupby('id')[index].mean() for index in idx]
>>> df_new = pd.DataFrame(
... [[x/y*100 for x, y in zip(lst2,sum(lst))] for lst2 in lst],
... index=idx, columns=df['id'].unique())
这样可行,但我不确定是否保证列或行按正确顺序命名,或者是否可能,例如a
列名为b
,反之亦然。
所以我的实际问题是,是否有更好,更清洁,更安全,更有效的方法。
答案 0 :(得分:2)
是的,有。
DataFrame.div
(或除法运算符__div__
)
v = df.groupby('id').mean()
v.T / v.sum(1) * 100 # thanks to @fuglede
# v.div(v.sum(1), axis=0).T # thanks to @Scott Boston
id a b
val 66.666667 42.857143
val2 33.333333 57.142857