重命名pandas中的列

use*_*276 1601 python replace rename dataframe pandas

我有一个使用pandas和列标签的DataFrame,我需要编辑它来替换原始列标签.

我想更改A原始列名称所在的DataFrame 中的列名:

['$a', '$b', '$c', '$d', '$e'] 
Run Code Online (Sandbox Code Playgroud)

['a', 'b', 'c', 'd', 'e'].
Run Code Online (Sandbox Code Playgroud)

我将已编辑的列名存储在列表中,但我不知道如何替换列名.

lex*_*ual 2561

使用该df.rename()函数并引用要重命名的列.并非所有列都必须重命名:

df = df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'})
# Or rename the existing DataFrame (rather than creating a copy) 
df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'}, inplace=True)
Run Code Online (Sandbox Code Playgroud)

  • 当我在这个答案中使用第二个代码片段时,我得到了可怕的`SettingWithCopyWarning:`. (11认同)
  • 第一个解决方案:`df = df.rename(columns = {'oldName1':'newName1','oldName2':'newName2'})`更改显示的名称,但更改基础数据结构中的_not_元素.所以如果你尝试`df ['newName1']`你会得到一个错误.`inplace = True`是必要的,以避免gotchya. (11认同)
  • 哦,我找到了 - 下面的答案!http://stackoverflow.com/a/16667215/2230844 (3认同)
  • 当我使用6列数据框(dataframe <按enter>)时,缩写表示:`code` <class'pandas.core.frame.DataFrame'> Int64Index:1000个条目,0到999数据列:BodyMarkdown 1000 non -null`code`有效,但是当我执行dataframe.head()时,列的旧名称会重新出现. (2认同)

eum*_*iro 1627

只需将其分配给.columns属性:

>>> df = pd.DataFrame({'$a':[1,2], '$b': [10,20]})
>>> df.columns = ['a', 'b']
>>> df
   a   b
0  1  10
1  2  20
Run Code Online (Sandbox Code Playgroud)

  • @ericmjl yes`df.rename(columns = {'$ b':'B'},inplace = True) (391认同)
  • 是否可以更改单个列标题名称? (269认同)
  • @ericmjl:假设您要更改df的第一个变量的名称.然后你可以这样做:`new_columns = df.columns.values; ``new_columns [0] ='XX';``df.columns = new_columns` (99认同)
  • 看起来你可以简单地完成df.columns.values [0] ='XX' (47认同)
  • 开个玩笑,@ RAY - 不要这样做.看起来这是一个独立于列名称存储索引的列表.破坏你的df的列命名是一个不错的工作...... (23认同)
  • 这种方法很脆弱.请参阅下面的[@ lexual的回答](/sf/answers/794839531/)和其他人.Pandas提供`rename`方法是有原因的. (5认同)
  • 这是非常脆弱的;即使您只想更改少数列,它也需要指定所有列,并且与列语义无关,而是与它们的(非物质)位置相关。您绝对应该使用 `rename` 并为要更改的列提供映射。在这种情况下,`{c: c.lstrip('$') for c in df.columns}` 会好得多。 (5认同)
  • @MitchFlax谢谢.我现在也看到了.令人失望的行为,但它是如何.看起来你可以通过调用<code> df.columns = df.columns.values </ code>来恢复.这有多奇怪. (4认同)
  • 此方法要求您引用每个现有列名称.在处理具有大量列的DataFrame时不太实用 (3认同)
  • @cd98,为什么不只是 ```new_columns = df.columns;``` 而不是 ```new_columns = df.columns.values;``` ? (3认同)

And*_*den 368

rename方法可以采用一种功能,例如:

In [11]: df.columns
Out[11]: Index([u'$a', u'$b', u'$c', u'$d', u'$e'], dtype=object)

In [12]: df.rename(columns=lambda x: x[1:], inplace=True)

In [13]: df.columns
Out[13]: Index([u'a', u'b', u'c', u'd', u'e'], dtype=object)
Run Code Online (Sandbox Code Playgroud)

  • 尼斯.这个节省了我的一天:`df.rename(columns = lambda x:x.lstrip(),inplace = True) (53认同)
  • `df.rename(columns = lambda x:x.replace('','_'),inplace = True)`是一个gem,这样我们就可以编写`df.Column_1_Name`而不是写`df.loc [:, '第1列名称']`. (4认同)
  • 类似于@ root-11 -在我的情况下,在IPython控制台输出中没有打印出一个项目符号字符,因此我需要删除的不只是空格(条带),所以:`t.columns = t.columns。 str.replace(r'[^ \ x00- \ x7F] +','')` (2认同)

Ted*_*rou 159

熊猫0.21+答案

版本0.21中的列重命名有一些重要更新.

  • rename方法添加了axis可以设置为columns或的参数1.此更新使此方法与其余的pandas API匹配.它仍然具有indexcolumns参数,但您不再被迫使用它们.
  • 使用set 的set_axis方法可以使用列表重命名所有索引或列标签.inplaceFalse

Pandas 0.21+的例子

构造示例DataFrame:

df = pd.DataFrame({'$a':[1,2], '$b': [3,4], 
                   '$c':[5,6], '$d':[7,8], 
                   '$e':[9,10]})

   $a  $b  $c  $d  $e
0   1   3   5   7   9
1   2   4   6   8  10
Run Code Online (Sandbox Code Playgroud)

使用renameaxis='columns'axis=1

df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis='columns')
Run Code Online (Sandbox Code Playgroud)

要么

df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis=1)
Run Code Online (Sandbox Code Playgroud)

两者都导致以下结果:

   a  b  c  d   e
0  1  3  5  7   9
1  2  4  6  8  10
Run Code Online (Sandbox Code Playgroud)

仍然可以使用旧方法签名:

df.rename(columns={'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'})
Run Code Online (Sandbox Code Playgroud)

rename函数还接受将应用于每个列名称的函数.

df.rename(lambda x: x[1:], axis='columns')
Run Code Online (Sandbox Code Playgroud)

要么

df.rename(lambda x: x[1:], axis=1)
Run Code Online (Sandbox Code Playgroud)

使用set_axis列表和inplace=False

您可以为set_axis方法提供一个列表,该列表的长度与列数(或索引)相等.目前,inplace默认为True,但在将来的版本inplace中将默认为默认值False.

df.set_axis(['a', 'b', 'c', 'd', 'e'], axis='columns', inplace=False)
Run Code Online (Sandbox Code Playgroud)

要么

df.set_axis(['a', 'b', 'c', 'd', 'e'], axis=1, inplace=False)
Run Code Online (Sandbox Code Playgroud)

为什么不用df.columns = ['a', 'b', 'c', 'd', 'e']

像这样直接分配列没有任何问题.这是一个非常好的解决方案.

使用的优点set_axis是它可以用作方法链的一部分,并返回DataFrame的新副本.没有它,您必须在重新分配列之前将链的中间步骤存储到另一个变量.

# new for pandas 0.21+
df.some_method1()
  .some_method2()
  .set_axis()
  .some_method3()

# old way
df1 = df.some_method1()
        .some_method2()
df1.columns = columns
df1.some_method3()
Run Code Online (Sandbox Code Playgroud)

  • df.columns = ['a','b','c','d','e']似乎不再起作用,使用0.22版时,我有一个警告说* Pandas不允许创建列通过新的属性名称*。如果我所有的列都被称为相同的,如何重命名:/ (3认同)

pau*_*ip3 128

由于您只想删除所有列名中的$符号,您可以这样做:

df = df.rename(columns=lambda x: x.replace('$', ''))
Run Code Online (Sandbox Code Playgroud)

要么

df.rename(columns=lambda x: x.replace('$', ''), inplace=True)
Run Code Online (Sandbox Code Playgroud)

  • 这不仅对 OP 的情况有帮助,而且对一般要求也有帮助。例如:用分隔符分割列名并使用其中的一部分。 (3认同)

Nir*_*oda 96

在 Pandas 中重命名列是一项简单的任务。

df.rename(columns={'$a': 'a', '$b': 'b', '$c': 'c', '$d': 'd', '$e': 'e'}, inplace=True)
Run Code Online (Sandbox Code Playgroud)

  • 我会提出这个,因为它自然受到支持。 (2认同)
  • 这里的“columns”参数也可以是一个函数。因此,如果你想从每个名称中删除第一个字符,你可以执行 `df.rename(columns=lambda name: name[1:], inplace=True)` ([ref](https://pandas.pydata.org /docs/user_guide/basics.html#basics-rename)) (2认同)

M P*_*AUL 74

df.columns = ['a', 'b', 'c', 'd', 'e']
Run Code Online (Sandbox Code Playgroud)

它将按您提供的顺序用您提供的名称替换现有名称.

  • 不要修改`df.columns.values`,这是错误的./sf/ask/3030424701/ (5认同)

mig*_*loo 58

old_names = ['$a', '$b', '$c', '$d', '$e'] 
new_names = ['a', 'b', 'c', 'd', 'e']
df.rename(columns=dict(zip(old_names, new_names)), inplace=True)
Run Code Online (Sandbox Code Playgroud)

这样您就可以根据需要手动编辑new_names.当您只需要重命名几列以纠正错误拼写,重音,删除特殊字符等时,效果很好.

  • 我喜欢这种方法,但我认为 `df.columns = ['a', 'b', 'c', 'd', 'e']` 更简单。 (3认同)
  • 我喜欢这种压缩新旧名称的方法。我们可以使用 `df.columns.values` 来获取旧名称。 (2认同)

piR*_*red 34

一线或管道解决方案

我会专注于两件事:

  1. OP明确指出

    我将已编辑的列名存储在列表中,但我不知道如何替换列名.

    我不想解决如何替换'$'或剥离每个列标题的第一个字符的问题.OP已经完成了这一步.相反,我想专注于columns使用给定替换列名列表的新对象替换现有对象.

  2. df.columns = newnew新列名称的列表在哪里就像它获得的一样简单.这种方法的缺点是它需要编辑现有数据框的columns属性,而不是内联.我将通过流水线技术展示一些方法来执行此操作,而无需编辑现有的数据帧.


设置1
为了专注于需要使用预先存在的列表重命名替换列名称,我将创建一个df具有初始列名称和不相关的新列名称的新样本数据框.

df = pd.DataFrame({'Jack': [1, 2], 'Mahesh': [3, 4], 'Xin': [5, 6]})
new = ['x098', 'y765', 'z432']

df

   Jack  Mahesh  Xin
0     1       3    5
1     2       4    6
Run Code Online (Sandbox Code Playgroud)

解决方案1
pd.DataFrame.rename

已经说过,如果你有一个将旧列名称映射到新列名的字典,你可以使用pd.DataFrame.rename.

d = {'Jack': 'x098', 'Mahesh': 'y765', 'Xin': 'z432'}
df.rename(columns=d)

   x098  y765  z432
0     1     3     5
1     2     4     6
Run Code Online (Sandbox Code Playgroud)

但是,您可以轻松创建该字典并将其包含在调用中rename.以下内容利用了迭代时df,我们迭代每个列名称的事实.

# given just a list of new column names
df.rename(columns=dict(zip(df, new)))

   x098  y765  z432
0     1     3     5
1     2     4     6
Run Code Online (Sandbox Code Playgroud)

如果原始列名称是唯一的,则此方法很有用.但如果他们不是,那么这就会崩溃.


设置2个
非唯一列

df = pd.DataFrame(
    [[1, 3, 5], [2, 4, 6]],
    columns=['Mahesh', 'Mahesh', 'Xin']
)
new = ['x098', 'y765', 'z432']

df

   Mahesh  Mahesh  Xin
0       1       3    5
1       2       4    6
Run Code Online (Sandbox Code Playgroud)

解决方案2
pd.concat使用keys参数

首先,注意当我们尝试使用解决方案1时会发生什么:

df.rename(columns=dict(zip(df, new)))

   y765  y765  z432
0     1     3     5
1     2     4     6
Run Code Online (Sandbox Code Playgroud)

我们没有将new列表映射为列名.我们最后重复了一遍y765.相反,我们可以在遍历列的时候使用函数的keys参数.pd.concatdf

pd.concat([c for _, c in df.items()], axis=1, keys=new) 

   x098  y765  z432
0     1     3     5
1     2     4     6
Run Code Online (Sandbox Code Playgroud)

解决方案3
重建.仅当您dtype对所有列都有一个时,才应使用此选项.否则,您将最终dtype object获得所有列并将其转换回来需要更多的字典工作.

dtype

pd.DataFrame(df.values, df.index, new)

   x098  y765  z432
0     1     3     5
1     2     4     6
Run Code Online (Sandbox Code Playgroud)

dtype

pd.DataFrame(df.values, df.index, new).astype(dict(zip(new, df.dtypes)))

   x098  y765  z432
0     1     3     5
1     2     4     6
Run Code Online (Sandbox Code Playgroud)

解决方案4
这是一个花哨的伎俩transposeset_index. pd.DataFrame.set_index允许我们设置内联索引,但没有相应的set_columns.所以我们可以转置,然后set_index转置回来.但是,解决方案3中的相同单一dtype与混合dtype警告适用于此处.

dtype

df.T.set_index(np.asarray(new)).T

   x098  y765  z432
0     1     3     5
1     2     4     6
Run Code Online (Sandbox Code Playgroud)

dtype

df.T.set_index(np.asarray(new)).T.astype(dict(zip(new, df.dtypes)))

   x098  y765  z432
0     1     3     5
1     2     4     6
Run Code Online (Sandbox Code Playgroud)

溶液5
使用lambdapd.DataFrame.rename通过的每个元素的周期new
.在该方案中,我们通过一个lambda即需要x但随后会忽略它.它也需要一个y但不期望它.相反,迭代器作为默认值给出,然后我可以使用它一次循环一个迭代器,而不考虑其值x.

df.rename(columns=lambda x, y=iter(new): next(y))

   x098  y765  z432
0     1     3     5
1     2     4     6
Run Code Online (Sandbox Code Playgroud)

而作为在乡亲向我指出sopython聊天,如果我添加了一个*在之间xy,我可以保护我的y变量.虽然,在这种情况下,我不相信它需要保护.值得一提的是.

df.rename(columns=lambda x, *, y=iter(new): next(y))

   x098  y765  z432
0     1     3     5
1     2     4     6
Run Code Online (Sandbox Code Playgroud)

  • 也许我们可以添加 `df.rename(lambda x : x.lstrip('$'),axis=1) ` (2认同)

fir*_*ynx 33

列名与系列名称

我想解释一下幕后发生的事情.

数据帧是一组系列.

系列又是a的延伸 numpy.array

numpy.array有财产 .name

这是该系列的名称.很少有熊猫尊重这个属性,但它在某些地方徘徊,可以用来破解一些熊猫行为.

命名列的列表

这里有很多答案谈论df.columns属性是什么list时候实际上它是一个Series.这意味着它有一个.name属性.

如果您决定填写列的名称,会发生这种情况Series:

df.columns = ['column_one', 'column_two']
df.columns.names = ['name of the list of columns']
df.index.names = ['name of the index']

name of the list of columns     column_one  column_two
name of the index       
0                                    4           1
1                                    5           2
2                                    6           3
Run Code Online (Sandbox Code Playgroud)

请注意,索引的名称总是低一列.

徘徊的文物

.name属性有时会持续存在.如果你设置df.columns = ['one', 'two']那么df.one.name将是'one'.

如果你设定df.one.name = 'three'那么df.columns仍然会给你['one', 'two'],并df.one.name会给你'three'

pd.DataFrame(df.one) 将返回

    three
0       1
1       2
2       3
Run Code Online (Sandbox Code Playgroud)

因为pandas重用.name已经定义的Series.

多级列名称

Pandas有办法做多层列名.没有太多的魔法涉及但我想在我的答案中也涵盖这个,因为我没有看到有人在这里接受这个.

    |one            |
    |one      |two  |
0   |  4      |  1  |
1   |  5      |  2  |
2   |  6      |  3  |
Run Code Online (Sandbox Code Playgroud)

通过将列设置为列表可以轻松实现这一点,如下所示:

df.columns = [['one', 'one'], ['one', 'two']]
Run Code Online (Sandbox Code Playgroud)


Ama*_*mar 32

让我们通过一个小例子来理解重命名......

  1. 使用映射重命名列:

     df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}) # Creating a df with column name A and B
     df.rename({"A": "new_a", "B": "new_b"}, axis='columns', inplace =True) # Renaming column A with 'new_a' and B with 'new_b'
    
     Output:
    
        new_a  new_b
     0  1       4
     1  2       5
     2  3       6
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用映射重命名 index/Row_Name:

     df.rename({0: "x", 1: "y", 2: "z"}, axis='index', inplace =True) # Row name are getting replaced by 'x', 'y', and 'z'.
    
     Output:
    
            new_a  new_b
         x  1       4
         y  2       5
         z  3       6
    
    Run Code Online (Sandbox Code Playgroud)


小智 22

如果您已经有了新列名称的列表,您可以尝试以下操作:

new_cols = ['a', 'b', 'c', 'd', 'e']
new_names_map = {df.columns[i]:new_cols[i] for i in range(len(new_cols))}

df.rename(new_names_map, axis=1, inplace=True)
Run Code Online (Sandbox Code Playgroud)


and*_*ens 16

如果你有数据帧,df.columns将所有内容转储到你可以操作的列表中,然后作为列的名称重新分配到你的数据帧中......

columns = df.columns
columns = [row.replace("$","") for row in columns]
df.rename(columns=dict(zip(columns, things)), inplace=True)
df.head() #to validate the output
Run Code Online (Sandbox Code Playgroud)

最好的办法?IDK.一种方式 - 是的.

评估问题答案中提出的所有主要技术的更好方法是使用cProfile来计算内存和执行时间.@kadee,@ kaitlyn和@eumiro具有执行时间最快的功能 - 尽管这些功能如此之快,我们正在比较所有答案的.000和.001秒的舍入.道德:我上面的回答很可能不是'最好'的方式.

import pandas as pd
import cProfile, pstats, re

old_names = ['$a', '$b', '$c', '$d', '$e']
new_names = ['a', 'b', 'c', 'd', 'e']
col_dict = {'$a': 'a', '$b': 'b','$c':'c','$d':'d','$e':'e'}

df = pd.DataFrame({'$a':[1,2], '$b': [10,20],'$c':['bleep','blorp'],'$d':[1,2],'$e':['texa$','']})

df.head()

def eumiro(df,nn):
    df.columns = nn
    #This direct renaming approach is duplicated in methodology in several other answers: 
    return df

def lexual1(df):
    return df.rename(columns=col_dict)

def lexual2(df,col_dict):
    return df.rename(columns=col_dict, inplace=True)

def Panda_Master_Hayden(df):
    return df.rename(columns=lambda x: x[1:], inplace=True)

def paulo1(df):
    return df.rename(columns=lambda x: x.replace('$', ''))

def paulo2(df):
    return df.rename(columns=lambda x: x.replace('$', ''), inplace=True)

def migloo(df,on,nn):
    return df.rename(columns=dict(zip(on, nn)), inplace=True)

def kadee(df):
    return df.columns.str.replace('$','')

def awo(df):
    columns = df.columns
    columns = [row.replace("$","") for row in columns]
    return df.rename(columns=dict(zip(columns, '')), inplace=True)

def kaitlyn(df):
    df.columns = [col.strip('$') for col in df.columns]
    return df

print 'eumiro'
cProfile.run('eumiro(df,new_names)')
print 'lexual1'
cProfile.run('lexual1(df)')
print 'lexual2'
cProfile.run('lexual2(df,col_dict)')
print 'andy hayden'
cProfile.run('Panda_Master_Hayden(df)')
print 'paulo1'
cProfile.run('paulo1(df)')
print 'paulo2'
cProfile.run('paulo2(df)')
print 'migloo'
cProfile.run('migloo(df,old_names,new_names)')
print 'kadee'
cProfile.run('kadee(df)')
print 'awo'
cProfile.run('awo(df)')
print 'kaitlyn'
cProfile.run('kaitlyn(df)')
Run Code Online (Sandbox Code Playgroud)


Ale*_*der 16

df = pd.DataFrame({'$a': [1], '$b': [1], '$c': [1], '$d': [1], '$e': [1]})
Run Code Online (Sandbox Code Playgroud)

如果新的列列表与现有列的顺序相同,则分配很简单:

new_cols = ['a', 'b', 'c', 'd', 'e']
df.columns = new_cols
>>> df
   a  b  c  d  e
0  1  1  1  1  1
Run Code Online (Sandbox Code Playgroud)

如果您将旧列名称上的字典键入新列名称,则可以执行以下操作:

d = {'$a': 'a', '$b': 'b', '$c': 'c', '$d': 'd', '$e': 'e'}
df.columns = df.columns.map(lambda col: d[col])  # Or `.map(d.get)` as pointed out by @PiRSquared.
>>> df
   a  b  c  d  e
0  1  1  1  1  1
Run Code Online (Sandbox Code Playgroud)

如果您没有列表或字典映射,则可以$通过列表理解去除前导符号:

df.columns = [col[1:] if col[0] == '$' else col for col in df]
Run Code Online (Sandbox Code Playgroud)

  • 而不是`lambda col:d [col]`你可以传递`d.get` ...所以它看起来像`df.columns.map(d.get)` (2认同)

kai*_*ait 12

我们可以替换原始列标签的另一种方法是从原始列标签中剥离不需要的字符(此处为"$").

这可以通过在df.columns上运行for循环并将剥离的列附加到df.columns来完成.

相反,我们可以通过使用下面的列表理解在一个语句中巧妙地做到这一点:

df.columns = [col.strip('$') for col in df.columns]
Run Code Online (Sandbox Code Playgroud)

(stripPython中的方法从字符串的开头和结尾剥离给定的字符.)

  • 你能解释一下这是怎么回事?这将使答案对未来的读者更有价值. (2认同)

Tho*_*s P 11

真正的简单只是使用

df.columns = ['Name1', 'Name2', 'Name3'...]
Run Code Online (Sandbox Code Playgroud)

它将按照您放置的顺序分配列名称


Ant*_*pov 9

你可以用str.slice它:

df.columns = df.columns.str.slice(1)
Run Code Online (Sandbox Code Playgroud)

  • PS:这是一个更详细的等效于“df.columns.str[1:]”...可能更好使用它,它更短、更明显。 (2认同)

Ani*_*l_M 9

我知道这个问题和答案已被咀嚼致死.但我提到它是为了解决我遇到的问题之一.我能够使用来自不同答案的点点滴滴来解决它,从而在任何人需要时提供我的回复.

我的方法是通用的,您可以通过逗号分隔delimiters=变量和面向未来的方法添加其他分隔符.

工作守则:

import pandas as pd
import re


df = pd.DataFrame({'$a':[1,2], '$b': [3,4],'$c':[5,6], '$d': [7,8], '$e': [9,10]})

delimiters = '$'
matchPattern = '|'.join(map(re.escape, delimiters))
df.columns = [re.split(matchPattern, i)[1] for i in df.columns ]
Run Code Online (Sandbox Code Playgroud)

输出:

>>> df
   $a  $b  $c  $d  $e
0   1   3   5   7   9
1   2   4   6   8  10

>>> df
   a  b  c  d   e
0  1  3  5  7   9
1  2  4  6  8  10
Run Code Online (Sandbox Code Playgroud)


小智 9

如果您只想删除“$”符号,请使用以下代码

df.columns = pd.Series(df.columns.str.replace("$", ""))
Run Code Online (Sandbox Code Playgroud)


oxe*_*xer 8

请注意,这些方法不适用于MultiIndex.对于MultiIndex,您需要执行以下操作:

>>> df = pd.DataFrame({('$a','$x'):[1,2], ('$b','$y'): [3,4], ('e','f'):[5,6]})
>>> df
   $a $b  e
   $x $y  f
0  1  3  5
1  2  4  6
>>> rename = {('$a','$x'):('a','x'), ('$b','$y'):('b','y')}
>>> df.columns = pandas.MultiIndex.from_tuples([
        rename.get(item, item) for item in df.columns.tolist()])
>>> df
   a  b  e
   x  y  f
0  1  3  5
1  2  4  6
Run Code Online (Sandbox Code Playgroud)


sbh*_*bha 8

另一种选择是使用正则表达式重命名:

import pandas as pd
import re

df = pd.DataFrame({'$a':[1,2], '$b':[3,4], '$c':[5,6]})

df = df.rename(columns=lambda x: re.sub('\$','',x))
>>> df
   a  b  c
0  1  3  5
1  2  4  6
Run Code Online (Sandbox Code Playgroud)


Str*_*ker 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)
Run Code Online (Sandbox Code Playgroud)

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


小智 8

许多 Pandas 函数都有一个 inplace 参数。将其设置为 True 时,转换直接应用于您调用它的数据帧。例如:

df = pd.DataFrame({'$a':[1,2], '$b': [3,4]})
df.rename(columns={'$a': 'a'}, inplace=True)
df.columns

>>> Index(['a', '$b'], dtype='object')
Run Code Online (Sandbox Code Playgroud)

或者,在某些情况下您希望保留原始数据帧。如果创建数据框是一项昂贵的任务,我经常看到人们陷入这种情况。例如,如果创建数据框需要查询雪花数据库。在这种情况下,只需确保将 inplace 参数设置为 False。

df = pd.DataFrame({'$a':[1,2], '$b': [3,4]})
df2 = df.rename(columns={'$a': 'a'}, inplace=False)
df.columns
    
>>> Index(['$a', '$b'], dtype='object')

df2.columns

>>> Index(['a', '$b'], dtype='object')
Run Code Online (Sandbox Code Playgroud)

如果您经常进行这些类型的转换,您还可以查看许多不同的 Pandas GUI 工具。我是一个叫做Mito的创造者。它是一个电子表格,可自动将您的编辑转换为 Python 代码。


Mai*_*and 8

我的一行答案是

\n

df.columns = df_new_cols

\n

这是最好的一种,处理时间只有 1/3。

\n

timeit比较:

\n

df有七列。我正在尝试更改其中一些名称。

\n
%timeit df.rename(columns={old_col:new_col for (old_col,new_col) in zip(df_old_cols,df_new_cols)},inplace=True)\n214 \xc2\xb5s \xc2\xb1 10.1 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000 loops each)\n\n%timeit df.rename(columns=dict(zip(df_old_cols,df_new_cols)),inplace=True)\n212 \xc2\xb5s \xc2\xb1 7.7 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000 loops each)\n\n%timeit df.columns = df_new_cols\n72.9 \xc2\xb5s \xc2\xb1 17.2 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 10000 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n


Omr*_*mri 8

一个简单且“有趣”(和Pythonic?)的解决方案:

df.rename(columns={x: x.replace('$', '') for x in df.columns})
Run Code Online (Sandbox Code Playgroud)

在哪里:

df = pd.DataFrame(columns=['$a', '$b', '$c', '$d', '$e'])
Run Code Online (Sandbox Code Playgroud)

脚步:

获取 DataFrame 的列作为列表:

df.columns
Run Code Online (Sandbox Code Playgroud)

在DataFrames中重命名的方法:

df.rename()
Run Code Online (Sandbox Code Playgroud)

用于指定要重命名列的属性:

columns={}
Run Code Online (Sandbox Code Playgroud)

在字典中,您需要指定要重命名的列(在每个键中)以及它们将获得哪些新名称(每个值)

{'old_col_name': 'new_col_name', ...}
Run Code Online (Sandbox Code Playgroud)

由于您的更改遵循某种模式,为了删除每列中的 $ 字符,我们可以使用字典理解:

{x: x.replace('$', '') for x in df.columns}
Run Code Online (Sandbox Code Playgroud)


小智 7

假设这是您的数据框。

在此处输入图片说明

您可以使用两种方法重命名列。

  1. 使用 dataframe.columns=[#list]

    df.columns=['a','b','c','d','e']
    
    Run Code Online (Sandbox Code Playgroud)

    在此处输入图片说明

    此方法的局限性在于,如果必须更改一列,则必须传递完整的列列表。同样,此方法不适用于索引标签。例如,如果您通过以下操作:

    df.columns = ['a','b','c','d']
    
    Run Code Online (Sandbox Code Playgroud)

    这将引发错误。长度不匹配:预期轴有5个元素,新值有4个元素。

  2. 另一种方法是Pandas rename()方法,用于重命名任何索引,列或行

    df = df.rename(columns={'$a':'a'})
    
    Run Code Online (Sandbox Code Playgroud)

    在此处输入图片说明

同样,您可以更改任何行或列。


小智 6

如果您必须处理无法由提供系统命名的列负载,那么我想出了以下方法,该方法将一次通用方法与特定替换方法结合在一起。

首先,使用正则表达式从数据框的列名称中创建字典,以丢弃某些列名称的附录,然后向字典中添加特定的替换内容,以便稍后在接收数据库中按预期命名核心列。

然后将其一次性应用到数据帧。

dict=dict(zip(df.columns,df.columns.str.replace('(:S$|:C1$|:L$|:D$|\.Serial:L$)','')))
dict['brand_timeseries:C1']='BTS'
dict['respid:L']='RespID'
dict['country:C1']='CountryID'
dict['pim1:D']='pim_actual'
df.rename(columns=dict, inplace=True)
Run Code Online (Sandbox Code Playgroud)


see*_*spi 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
Run Code Online (Sandbox Code Playgroud)

以下是它如何工作的示例:

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')
Run Code Online (Sandbox Code Playgroud)

  • 像这样的函数的用例极其罕见。在大多数情况下,我知道我在寻找什么以及我想将其重命名为什么,我只需自己分配/修改它即可。 (2认同)

小智 6

假设您可以使用正则表达式,此解决方案消除了使用正则表达式手动编码的需要:

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
Run Code Online (Sandbox Code Playgroud)

  • 在 Stack Overflow 上添加一个关于为什么您的解决方案应该有效或比现有解决方案更好的解释是一种很好的做法。有关更多信息,请阅读 [如何回答](//stackoverflow.com/help/how-to-answer)。 (2认同)

Igo*_*nko 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)
Run Code Online (Sandbox Code Playgroud)

  • FWIW,您可以只跟踪单独的 *n* 维列表中的列,并仅将底层 NumPy 数组/矩阵传递给 XGBoost,该数组/矩阵没有任何标题。通过这种方式,您可以将列命名为您想要的任何名称,而不必符合 XGBoost 的要求 (2认同)