我想从
['$a', '$b', '$c', '$d', '$e']
to
['a', 'b', 'c', 'd', 'e']
我想从
['$a', '$b', '$c', '$d', '$e']
to
['a', 'b', 'c', 'd', 'e']
当前回答
另一个选项是使用正则表达式重命名:
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
其他回答
只需将其分配给.columns属性:
>>> df = pd.DataFrame({'$a':[1,2], '$b': [10,20]})
>>> df
$a $b
0 1 10
1 2 20
>>> df.columns = ['a', 'b']
>>> df
a b
0 1 10
1 2 20
重命名特定列
使用df.reame()函数并引用要重命名的列。并非所有列都必须重命名:
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)
最小代码示例
df = pd.DataFrame('x', index=range(3), columns=list('abcde'))
df
a b c d e
0 x x x x x
1 x x x x x
2 x x x x x
以下方法都可以工作并产生相同的输出:
df2 = df.rename({'a': 'X', 'b': 'Y'}, axis=1) # new method
df2 = df.rename({'a': 'X', 'b': 'Y'}, axis='columns')
df2 = df.rename(columns={'a': 'X', 'b': 'Y'}) # old method
df2
X Y c d e
0 x x x x x
1 x x x x x
2 x x x x x
请记住将结果指定回,因为修改不在原位。或者,指定inplace=True:
df.rename({'a': 'X', 'b': 'Y'}, axis=1, inplace=True)
df
X Y c d e
0 x x x x x
1 x x x x x
2 x x x x x
在v0.25中,如果指定了要重命名的无效列,还可以指定errors='raise'来引发错误。请参阅v0.25 rename()文档。
重新分配列标题
使用df.set_axis(),axis=1,inplace=False(返回副本)。
df2 = df.set_axis(['V', 'W', 'X', 'Y', 'Z'], axis=1, inplace=False)
df2
V W X Y Z
0 x x x x x
1 x x x x x
2 x x x x x
这将返回一个副本,但您可以通过设置inplace=True来修改DataFrame(这是<=0.24版本的默认行为,但将来可能会更改)。
您也可以直接分配标题:
df.columns = ['V', 'W', 'X', 'Y', 'Z']
df
V W X Y Z
0 x x x x x
1 x x x x x
2 x x x x x
如果您已经获得了数据帧,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
最佳方式?我不知道。一种方式——是的。
评估问题答案中提出的所有主要技术的更好方法如下:使用cProfile测量内存和执行时间@kadee、@kaitlyn和@eumiro拥有执行时间最快的函数-尽管这些函数非常快,但我们比较了所有答案的0.000和0.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)')
单线或管道解决方案
我将关注两件事:
OP明确规定我将编辑后的列名存储在列表中,但我不知道如何替换列名。我不想解决如何替换“$”或删除每个列标题的第一个字符的问题。OP已完成此步骤。相反,我希望集中精力在给定替换列名列表的情况下,用一个新的列对象替换现有的列对象。df.columns=new其中new是新列名称的列表,非常简单。这种方法的缺点是它需要编辑现有数据帧的columns属性,而且它不是内联的。我将展示一些通过流水线执行此操作的方法,而无需编辑现有的数据帧。
设置1为了关注用预先存在的列表重命名或替换列名的需要,我将创建一个新的示例dataframe 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
解决方案1pd.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
但是,您可以轻松地创建该字典并将其包含在重命名调用中。下面的内容利用了这样一个事实,即在对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
如果您的原始列名是唯一的,这将非常有用。但如果他们不是,那么这就失败了。
设置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
解决方案2pd.concat使用keys参数
首先,注意当我们尝试使用解决方案1时会发生什么:
df.rename(columns=dict(zip(df, new)))
y765 y765 z432
0 1 3 5
1 2 4 6
我们没有将新列表映射为列名。我们最终重复了y765。相反,我们可以在遍历df列时使用pd.concat函数的keys参数。
pd.concat([c for _, c in df.items()], axis=1, keys=new)
x098 y765 z432
0 1 3 5
1 2 4 6
解决方案3修复只有当所有列都有一个dtype时,才应使用此选项。否则,您将得到所有列的dtype对象,并且将它们转换回需要更多的字典工作。
单个数据类型
pd.DataFrame(df.values, df.index, new)
x098 y765 z432
0 1 3 5
1 2 4 6
混合数据类型
pd.DataFrame(df.values, df.index, new).astype(dict(zip(new, df.dtypes)))
x098 y765 z432
0 1 3 5
1 2 4 6
解决方案4这是一个带有转置和set_index的噱头。pd.DataFrame.set_index允许我们内联设置索引,但没有相应的set_columns。所以我们可以转置,然后设置索引,然后转置回去。然而,解决方案3中的单个数据类型与混合数据类型的警告同样适用于此。
单个数据类型
df.T.set_index(np.asarray(new)).T
x098 y765 z432
0 1 3 5
1 2 4 6
混合数据类型
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
解决方案5在pd.DataFrame.rename中使用循环遍历每个新元素的lambda。在这个解决方案中,我们传递一个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
正如sopyson聊天中的人向我指出的那样,如果我在x和y之间添加一个*,我可以保护y变量。不过,在这种情况下,我不认为它需要保护。这仍然值得一提。
df.rename(columns=lambda x, *, y=iter(new): next(y))
x098 y765 z432
0 1 3 5
1 2 4 6
# This way it will work
import pandas as pd
# Define a dictionary
rankings = {'test': ['a'],
'odi': ['E'],
't20': ['P']}
# Convert the dictionary into DataFrame
rankings_pd = pd.DataFrame(rankings)
# Before renaming the columns
print(rankings_pd)
rankings_pd.rename(columns = {'test':'TEST'}, inplace = True)