在pandas数据框中计算重复列的均值

2 投票
2 回答
2065 浏览
提问于 2025-04-18 07:23

我有一个数据表,里面有重复的列名,这些列名代表了重复的测量数据。

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

撰写回答