pyplot - python title位置
重命名熊猫中的列 (16)
DataFrame - df.rename()将工作。
df.rename(columns = {'Old Name':'New Name'})
df是您拥有的DataFrame, 旧名称是要更改的列名称,则新名称是您更改为的新名称。 这种DataFrame内置方法使事情变得更容易。
我有一个使用熊猫和列标签的DataFrame,我需要编辑以替换原始列标签。
我想更改DataFrame A
中的列名,其中原始列名是:
['$a', '$b', '$c', '$d', '$e']
至
['a', 'b', 'c', 'd', 'e'].
我将编辑过的列名存储在列表中,但我不知道如何替换列名。
一条线或管线解决方案
我将专注于两件事情:
OP明确指出
我将编辑过的列名存储在列表中,但我不知道如何替换列名。
我不想解决如何替换
'$'
或从每个列标题剥离第一个字符的问题。 OP已经完成了这一步。 相反,我想专注于使用替换列名称列表替换现有columns
对象。df.columns = new
其中new
是新列名称的列表,非常简单。 这种方法的缺点是它需要编辑现有的数据框的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
解决方案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
但是,您可以轻松创建该字典并将其包含在要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
如果您的原始列名是唯一的,这非常有效。 但如果他们不是,那么这就打破了。
设置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
解决方案2
pd.concat
使用keys
参数
首先,注意当我们尝试使用解决方案1时会发生什么情况:
df.rename(columns=dict(zip(df, new)))
y765 y765 z432
0 1 3 5
1 2 4 6
我们没有将new
列表映射为列名。 我们结束了重复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
object
,并将它们转换回来需要更多的字典工作。
单dtype
pd.DataFrame(df.values, df.index, new)
x098 y765 z432
0 1 3 5
1 2 4 6
混合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
解决方案4
这是一个带有transpose
和set_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
混合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
解决方案5
在pd.DataFrame.rename
中使用循环遍历new
每个元素的lambda
在这个解决方案中,我们传递一个需要x
但是忽略它的lambda。 它也需要一个y
但不期望它。 相反,迭代器是作为默认值给出的,然后我可以使用它循环一次,而不考虑x
的值。
df.rename(columns=lambda x, y=iter(new): next(y))
x098 y765 z432
0 1 3 5
1 2 4 6
正如sopython聊天中的人们指出的那样,如果我在x
和y
之间添加*
,我可以保护我的y
变量。 虽然在这种情况下,我不相信它需要保护。 它仍然值得一提。
df.rename(columns=lambda x, *, y=iter(new): next(y))
x098 y765 z432
0 1 3 5
1 2 4 6
熊猫0.21+答案
在版本0.21中对列重命名进行了一些重大更新。
-
rename
方法添加了可以设置为columns
或1
的axis
参数。 此更新使此方法与熊猫API的其余部分相匹配。 它仍然有index
和columns
参数,但你不再被迫使用它们。 - 将
set_axis
设置为False
的set_axis
方法使您可以使用列表重命名所有索引或列标签。
熊猫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
使用axis='columns'
或axis=1
rename
df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis='columns')
要么
df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis=1)
这两个结果如下:
a b c d e
0 1 3 5 7 9
1 2 4 6 8 10
仍然可以使用旧的方法签名:
df.rename(columns={'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'})
rename
函数还接受将应用于每个列名称的函数。
df.rename(lambda x: x[1:], axis='columns')
要么
df.rename(lambda x: x[1:], axis=1)
将set_axis
与list和set_axis
inplace=False
您可以向set_axis
方法提供一个列表,该列表的长度等于列数(或索引)的长度。 目前, inplace
默认为True
,但在将来的版本中inplace
默认为False
。
df.set_axis(['a', 'b', 'c', 'd', 'e'], axis='columns', inplace=False)
要么
df.set_axis(['a', 'b', 'c', 'd', 'e'], axis=1, inplace=False)
为什么不使用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()
df.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)
使用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)
另一种替代原始列标签的方法是从原始列标签中去除不需要的字符(这里是'$')。
这可以通过在df.columns上运行for循环并将删除的列添加到df.columns来完成。
相反,我们可以通过使用如下所示的列表理解,在单个语句中整齐地做到这一点:
df.columns = [col.strip('$') for col in df.columns]
(Python中的strip
方法从字符串的开头和结尾剥离给定的字符。)
如http://pandas.pydata.org/pandas-docs/stable/text.html所记录:
df.columns = df.columns.str.replace('$','')
如果你不想要行名df.columns = ['a', 'b',index=False]
如果您有数据框,则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
最好的办法? IDK。 一种方式 - 是的。
评估问题答案中提出的所有主要技术的更好方法是使用cProfile来测量内存和执行时间。 @kadee,@kaitlyn和@eumiro具有最快执行时间的功能 - 虽然这些功能非常快,但我们正在比较所有答案的.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)')
尝试这个。 这个对我有用
df.rename(index=str, columns={"$a": "a", "$b": "b", "$c" : "c", "$d" : "d", "$e" : "e"})
我认为这种方法很有用:
df.rename(columns={"old_column_name1":"new_column_name1", "old_column_name2":"new_column_name2"})
该方法允许您单独更改列名称。
既然你只想删除所有列名中的$符号,你可以这样做:
df = df.rename(columns=lambda x: x.replace('$', ''))
要么
df.rename(columns=lambda x: x.replace('$', ''), inplace=True)
请注意,这些方法不适用于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
这里有一个我喜欢用来减少打字的漂亮小功能:
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'])
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')
df = pd.DataFrame({'$a': [1], '$b': [1], '$c': [1], '$d': [1], '$e': [1]})
如果您的新列的列表与现有列的顺序相同,则分配很简单:
new_cols = ['a', 'b', 'c', 'd', 'e']
df.columns = new_cols
>>> df
a b c d e
0 1 1 1 1 1
如果您的旧字段名称上键入了新字段名称的字典,则可以执行以下操作:
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
如果您没有列表或字典映射,可以通过列表理解去掉前导$
符号:
df.columns = [col[1:] if col[0] == '$' else col for col in df]
df.columns = ['a', 'b', 'c', 'd', 'e']
它会按照您提供的顺序,用您提供的名称替换现有名称。
你也可以像这样通过索引来分配它们:
df.columns.values[2] = 'c' #renames the 2nd column to 'c' (in position #3)