在Pandas中重命名列名

2934
我想要更改Pandas DataFrame的列标签从
['$a', '$b', '$c', '$d', '$e']

to

['a', 'b', 'c', 'd', 'e']

9
您可能希望查看官方文档,其中包含有关重命名列标签的内容:https://pandas.pydata.org/pandas-docs/stable/user_guide/text.html - ccpizza
2
已浏览 5.6 百万次。这告诉我们 Pandas 是多么直观易用。 - mins
@mins 你想要什么?你更喜欢什么?dplyr?Spark?Polars?你只是根据一个问题的观点来评判整个库吗?做一个好的用户,而不是消极地思考。最好你看看pandas在SO上有多少问题,pandas正在接近最好的语言。 - rubengavidia0x
2
@rubengavidia0x:虽然我认为Pandas很强大,但我不认为我们可以说它易于使用。正如在这篇文章中指出的那样,已经有35种不同的方法来回答关于重命名列(重命名列...)的问题。 (https://www.dunderdata.com/blog/minimally-sufficient-pandas) - mins
36个回答

8

除了已提供的解决方案外,在读取文件时,您可以替换所有列。 我们可以使用namesheader = 0来完成这项任务。

首先,我们创建一个列名列表,以便作为我们的列名称:

import pandas as pd

ufo_cols = ['city', 'color reported', 'shape reported', 'state', 'time']
ufo.columns = ufo_cols

ufo = pd.read_csv('link to the file you are using', names = ufo_cols, header = 0)

在这种情况下,所有列名都将被替换为您在列表中拥有的名称。

7
假设您能够使用正则表达式,此解决方案消除了手动编码的需求,使用正则表达式:
import pandas as pd
import re

srch = re.compile(r"\w+")

data = pd.read_csv("CSV_FILE.csv")
cols = data.columns
new_cols = list(map(lambda v:v.group(), (list(map(srch.search, cols)))))
data.columns = new_cols

3
在 Stack Overflow 上,为了解释你的解决方案为什么有效或比现有的解决方案更好,最好添加一些解释。欲了解更多信息,请参阅 How To Answer - Samuel Liew
注意最佳答案需要某种形式的硬编码,而最差评答案仅需要描述性和过程性方法。 - Kaustubh J
1
有比这更好(更易读)的解决方案,也利用了正则表达式。这个操作对于简单的重命名来说做得太多了。还有一种危险,就是模式不匹配任何内容,这种情况下你没有处理错误的任何事情。 - cs95
关于“假设您可以使用正则表达式”:您是指“假设您不能使用正则表达式”(相反的情况)吗? - Peter Mortensen

6

下面是一个我喜欢使用的小巧函数,可以减少打字:

def rename(data, oldnames, newname):
    if type(oldnames) == str: # Input can be a string or list of strings
        oldnames = [oldnames] # When renaming multiple columns
        newname = [newname] # Make sure you pass the corresponding list of new names
    i = 0
    for name in oldnames:
        oldvar = [c for c in data.columns if name in c]
        if len(oldvar) == 0:
            raise ValueError("Sorry, couldn't find that column in the dataset")
        if len(oldvar) > 1: # Doesn't have to be an exact match
            print("Found multiple columns that matched " + str(name) + ": ")
            for c in oldvar:
                print(str(oldvar.index(c)) + ": " + str(c))
            ind = input('Please enter the index of the column you would like to rename: ')
            oldvar = oldvar[int(ind)]
        if len(oldvar) == 1:
            oldvar = oldvar[0]
        data = data.rename(columns = {oldvar : newname[i]})
        i += 1
    return data

以下是它的工作原理示例:
In [2]: df = pd.DataFrame(np.random.randint(0, 10, size=(10, 4)), columns = ['col1', 'col2', 'omg', 'idk'])
# First list = existing variables
# Second list = new names for those variables
In [3]: df = rename(df, ['col', 'omg'],['first', 'ohmy'])
Found multiple columns that matched col:
0: col1
1: col2

Please enter the index of the column you would like to rename: 0

In [4]: df.columns
Out[5]: Index(['first', 'col2', 'ohmy', 'idk'], dtype='object')

2
像这样的函数使用情况极为罕见。在大多数情况下,我知道我在寻找什么并且想要将其重命名,我会自己分配/修改它。 - cs95
1
@cs95,我倾向于处理大型的国家或国际调查,其中变量的编码变量名以前缀开头,具体取决于答案选项、李克特量表和分支(例如EDU_2913.443,EDU_2913.421等)。对于我处理这些类型数据集非常有用,但如果您不需要的话也可以理解 :) - seeiespi

6

我需要为XGBoost重命名特征,但它不喜欢以下任何一个名称:

import re
regex = r"[!\"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~ ]+"
X_trn.columns = X_trn.columns.str.replace(regex, '_', regex=True)
X_tst.columns = X_tst.columns.str.replace(regex, '_', regex=True)

2
顺便提一下,您可以在一个单独的n维列表中跟踪列,并将基础NumPy数组/矩阵传递给XGBoost,而不必担心头信息。这样,您可以随意命名列,而无需遵循XGBoost的要求。 - blacksite
1
它是什么样子的? - Peter Mortensen

3

在特定位置重命名列

这个页面上没有提到的一个用例是如何通过索引来重命名列,即在特定位置重命名列名。如果列名是唯一的,那么rename()方法就可以使用。例如,如果我们想要重命名第二列,可以使用以下方法。

df = pd.DataFrame({'$A': [1, 2], '$B': ['a', 'b']})
df.rename(columns={df.columns[1]: 'new'}, inplace=True)
#                  ^^^^^^^^^^^^^ <--- second column is renamed

result1

然而,如果列标签是非唯一的(这通常是首先通过索引重命名它的常见原因),上述方法将更改所有重复的列名。但是,pd.DataFrame().columns 是一个不可变的 pandas Index 对象,它是建立在一个(可变的)numpy ndarray 上的,可以使用 .values/.to_numpy() 作为视图进行访问。通过索引修改底层数组即可完成任务。
# modify the second column name
df = pd.DataFrame([[1, 'a', 1.2], [2, 'b', 3.4]], columns=['$A', '$B', '$B'])
df.columns[1] = 'new'             # <---- TypeError
df.columns.values[1] = 'new'      # <---- OK
df.columns.to_numpy()[1] = 'new'  # <---- OK

要以链式方法执行相同操作或创建数据框的新副本,需要更改整个列对象并使用set_axis()进行赋值。
# change the second column name
df = df.set_axis([*df.columns[:1], 'new', *df.columns[2:]], axis=1)

result2

str 方法

pd.DataFrame().columns 还定义了一个 .str 访问器,可以调用特定的字符串方法。对于问题中的用例,可以使用 removeprefix() 来删除前导的 '$'

df = pd.DataFrame({'$A': [1, 2], '$B': ['a', 'b']})
df.columns = df.columns.str.removeprefix('$')

result3


2

你可以使用 lstrip 或者 strip 方法来处理索引:

df.columns = df.columns.str.lstrip('$')

或者

cols = ['$a', '$b', '$c', '$d', '$e']
pd.Series(cols).str.lstrip('$').tolist()

输出:

['a', 'b', 'c', 'd', 'e']

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