用pandas数据框交换或替换具有多列的列名

3

我想在pandas中仅交换(交换)列名,最好使用一行代码。另一个问题是我有大约100个列,这导致我无法重新分配所有列名,因此我想要替换选定列名对。我不知道列的索引(它将变化),因此我必须使用列名。

我尝试了以下代码:

import pandas as pd

probes = {'Spam': [0.0,1.0],
        'Ham': [1.0,0.0],
        'PT011': [0.11,0.21],
        'PT012': [0.12,0.22],
        'PT021': [0.21,0.11],
        'PT022': [0.22,0.12]}

df = pd.DataFrame(probes,columns= ['Spam','Ham','PT011', 'PT012','PT021','PT022'])
print("Before renaming:\n",df)
df.rename(columns={'PT011':'PT021', 'PT012':'PT022','PT021':'PT011','PT022':'PT012'}, inplace=True)
print("After renaming:\n",df)

我得到了:

Before renaming:
    Spam  Ham  PT011  PT012  PT021  PT022
0   0.0  1.0   0.11   0.12   0.21   0.22
1   1.0  0.0   0.21   0.22   0.11   0.12
After renaming:
    Spam  Ham  PT021  PT022  PT011  PT012
0   0.0  1.0   0.11   0.12   0.21   0.22
1   1.0  0.0   0.21   0.22   0.11   0.12

但我希望有一个简单的一行代码可以实现交换列名,而不需要定义两对要交换的列名,只需定义一对要交换的列名,并保留数据,使用类似于loc或iloc属性:

df['PT011','PT012']=df['PT021','PT022']

带有预期输出(也希望按照提议的顺序)的内容如下:
   Spam  Ham   PT011  PT012  PT021  PT022
0   0.0  1.0   0.21   0.22   0.11   0.12
1   1.0  0.0   0.11   0.12   0.21   0.22

答案显示在以下链接中:Renaming columns in pandas,例如:
df.columns = df.columns.str.replace('PT011','PT021')

这种方法不适合我的情况,因为它仍然需要给出两个列名的对应关系,或者重新分配所有列的名称,并且不能给出所需的列顺序。

2个回答

7

我在pandas文档中发现了一个简单易懂的方法,可以进行数据索引和选择:数据索引和选择

df[['PT011','PT021']]=df[['PT021','PT011']]
df[['PT012','PT022']]=df[['PT022','PT012']]

使输出按照期望顺序呈现:

After renaming:
    Spam  Ham  PT011  PT012  PT021  PT022
0   0.0  1.0   0.21   0.22   0.11   0.12
1   1.0  0.0   0.11   0.12   0.21   0.22

4

如果你有一个可以用来映射东西的字典,那么这个方法就很好用。

df_map = {'PT011':'PT021', 'PT012':'PT022'}
df.columns = [{**df_map, **{v:k for k,v in df_map.items()}}.get(x, x) for x in df.columns]

>>> df
   Spam  Ham  PT021  PT022  PT011  PT012
0   0.0  1.0   0.11   0.12   0.21   0.22
1   1.0  0.0   0.21   0.22   0.11   0.12

或者您可以使用rename()来更加安全地操作。

df.rename(columns={**df_map, **{v:k for k,v in df_map.items()}}, inplace=True)

我不确定你说的“你不想给它两个名称来翻转”是什么意思。否则你怎么知道要交换哪些列呢?
至于你的后续问题:
df_map = {'PT011':'PT021', 'PT012':'PT022'}
df_column_order = df.columns.tolist()
df.rename(columns={**df_map, **{v:k for k,v in df_map.items()}}, inplace=True)
df = df.reindex(df_column_order, axis=1)

当我说我不想交换对时,我的意思是我不想采用以下方法: 'PT011':'PT021', 'PT012':'PT022','PT021':'PT011','PT022':'PT012' 而是采用以下方法: 'PT011':'PT021', 'PT012':'PT022' 下一个问题是如何保留以前的列顺序,以便列的顺序为: PT011 PT012 PT021 PT022 - Tomasz
啊,这样就更有意义了。 - CJR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接