在pandas数据框中计算重复列的均值
我有一个数据表,里面有重复的列名,这些列名代表了重复的测量数据。
df = pd.DataFrame({'A': randn(5), 'B': randn(5)})
df2 = pd.DataFrame({'A': randn(5), 'B': randn(5)})
df3 = pd.concat([df,df2], axis=1)
df3
A B A B
0 -0.875884 -0.298203 0.877414 1.282025
1 1.605602 -0.127038 -0.286237 0.572269
2 1.349540 -0.067487 0.126440 1.063988
3 -0.142809 1.282968 0.941925 -1.593592
4 -0.630353 1.888605 -1.176436 -1.623352
我想计算'A'和'B'列的平均值,这样数据表就能缩减为
A B
0 0.000765 0.491911
1 0.659682 0.222616
2 0.737990 0.498251
3 0.399558 -0.155312
4 -0.903395 0.132627
如果我使用常规的方法
df3['A'].mean(axis=1)
我会得到一个没有列名的序列,然后我需要根据每组列的平均值来创建一个新的数据表。而且,.groupby()这个方法似乎不允许你直接按列名分组,而是需要你提供列名,然后它会对索引进行排序。有没有什么简单的方法可以做到这一点?
顺便问一下:为什么
df = pd.DataFrame({'A': randn(5), 'B': randn(5), 'A': randn(5), 'B': randn(5)})
不会生成一个四列的数据表,而是把同名的列合并了呢?
2 个回答
1
你创建df3的方式有点奇怪,对于这个简单的情况,下面的代码就能正常工作:
In [86]:
df = pd.DataFrame({'A': randn(5), 'B': randn(5)})
df2 = pd.DataFrame({'A': randn(5), 'B': randn(5)})
print(df)
print(df2)
A B
0 -0.732807 -0.571942
1 -1.546377 -1.586371
2 0.638258 0.569980
3 -1.017427 1.395300
4 0.666853 -0.258473
[5 rows x 2 columns]
A B
0 0.589185 1.029062
1 -1.447809 -0.616584
2 -0.506545 0.432412
3 -1.168424 0.312796
4 1.390517 1.074129
[5 rows x 2 columns]
In [87]:
(df+df2)/2
Out[87]:
A B
0 -0.071811 0.228560
1 -1.497093 -1.101477
2 0.065857 0.501196
3 -1.092925 0.854048
4 1.028685 0.407828
[5 rows x 2 columns]
顺便回答一下你的附带问题,这和Pandas没什么关系,更多是和字典的构造有关:
In [88]:
{'A': randn(5), 'B': randn(5), 'A': randn(5), 'B': randn(5)}
Out[88]:
{'B': array([-0.03087831, -0.24416885, -2.29924624, 0.68849978, 0.41938536]),
'A': array([ 2.18471335, 0.68051101, -0.35759988, 0.54023489, 0.49029071])}
字典的键必须是唯一的,所以我猜在构造的时候,它只是把值重新分配给已经存在的键。
补充说明
如果你坚持要有重复的列,那你就得从这个基础上创建一个新的数据框,因为如果你更新'A'和'B'这两列,平均值还是会重复,因为这些列是重复的:
In [92]:
df3 = pd.concat([df,df2], axis=1)
new_df = pd.DataFrame()
new_df['A'], new_df['B'] = df3['A'].sum(axis=1)/df3['A'].shape[1], df3['B'].sum(axis=1)/df3['B'].shape[1]
new_df
Out[92]:
A B
0 -0.071811 0.228560
1 -1.497093 -1.101477
2 0.065857 0.501196
3 -1.092925 0.854048
4 1.028685 0.407828
[5 rows x 2 columns]
所以上面的代码可以在df3上运行,实际上对于任意数量的重复列都是适用的,这就是我使用shape的原因。如果你知道这些列只会重复一次,你可以直接写死为2。
6
你可以使用 level
这个关键词(在这种情况下,把你的列视为索引的第一层,也就是第0层,只有这一层):
In [11]: df3
Out[11]:
A B A B
0 -0.367326 -0.422332 2.379907 1.502237
1 -1.060848 0.083976 0.619213 -0.303383
2 0.805418 -0.109793 0.257343 0.186462
3 2.419282 -0.452402 0.702167 0.216165
4 -0.464248 -0.980507 0.823302 0.900429
In [12]: df3.mean(axis=1, level=0)
Out[12]:
A B
0 1.006291 0.539952
1 -0.220818 -0.109704
2 0.531380 0.038334
3 1.560725 -0.118118
4 0.179527 -0.040039