Renaming columns in pandas
我有一个使用panda和列标签的数据帧,我需要编辑它们来替换原始的列标签。
我想更改数据帧
1 | ['$a', '$b', '$c', '$d', '$e'] |
到
1 | ['a', 'b', 'c', 'd', 'e']. |
我已将编辑后的列名存储在列表中,但不知道如何替换列名。
使用
1 2 3 | 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) |
1 2 3 4 5 6 7 | 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) |
如http://pandas.pydata.org/pandas-docs/stable/text.html所述:
1 | df.columns = df.columns.str.replace('$','') |
熊猫0.21+答案
在0.21版本中,对列重命名进行了一些重要的更新。
rename 方法增加了axis 参数,可以设置为columns 或1 。此更新使此方法与熊猫API的其余部分相匹配。它仍然有index 和columns 参数,但您不再被迫使用它们。inplace 设置为False 的set_axis 方法允许您用列表重命名所有索引或列标签。
熊猫的例子0.21+
构造示例数据帧:
1 2 3 4 5 6 7 | 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 |
使用
1 | df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis='columns') |
或
1 | df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis=1) |
两者都会导致以下结果:
1 2 3 | a b c d e 0 1 3 5 7 9 1 2 4 6 8 10 |
仍然可以使用旧方法签名:
1 | df.rename(columns={'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}) |
1 | df.rename(lambda x: x[1:], axis='columns') |
或
1 | df.rename(lambda x: x[1:], axis=1) |
使用带列表的
您可以向
1 | df.set_axis(['a', 'b', 'c', 'd', 'e'], axis='columns', inplace=False) |
或
1 | df.set_axis(['a', 'b', 'c', 'd', 'e'], axis=1, inplace=False) |
为什么不使用
直接这样分配列没有任何错误。这是一个完美的解决方案。
使用
1 2 3 4 5 6 7 8 9 10 11 | # 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() |
因为您只想删除$sign-in所有的列名,所以您可以这样做:
1 | df = df.rename(columns=lambda x: x.replace('$', '')) |
或
1 | df.rename(columns=lambda x: x.replace('$', ''), inplace=True) |
1 | df.columns = ['a', 'b', 'c', 'd', 'e'] |
它将按您提供的顺序用您提供的名称替换现有的名称。
1 2 3 | 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) |
这样,您可以根据需要手动编辑
我认为这种方法很有用:
1 | df.rename(columns={"old_column_name1":"new_column_name1","old_column_name2":"new_column_name2"}) |
此方法允许您单独更改列名。
列名与序列名
我想解释一下幕后发生的事情。
数据帧是一组序列。
系列依次是
这是系列的名称。熊猫很少尊重这一属性,但它会在某些地方逗留,并可以用来攻击一些熊猫的行为。
命名列列表这里的很多答案都是关于
如果您决定填写列的名称
1 2 3 4 5 6 7 8 9 | 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 |
请注意,索引的名称总是低一列。
留下的文物如果你设置了
1 2 3 4 | three 0 1 1 2 2 3 |
因为熊猫会重复使用已经定义的
熊猫有多层次列名的方法。这里面没有太多的魔法,但我也想在我的答案中包含这一点,因为我没有看到任何人在这里发现这一点。
1 2 3 4 5 | |one | |one |two | 0 | 4 | 1 | 1 | 5 | 2 | 2 | 6 | 3 | |
这很容易通过将列设置为列表来实现,如下所示:
1 | df.columns = [['one', 'one'], ['one', 'two']] |
单线或管道解决方案
我将关注两件事:
OP明确说明
I have the edited column names stored it in a list, but I don't know how to replace the column names.
我不想解决如何替换
设置1为了关注用预先存在的列表重命名替换列名的需要,我将创建一个新的示例数据框
1 2 3 4 5 6 7 8 | 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
已经说过,如果您有一个字典将旧的列名映射到新的列名,那么您可以使用
1 2 3 4 5 6 | d = {'Jack': 'x098', 'Mahesh': 'y765', 'Xin': 'z432'} df.rename(columns=d) x098 y765 z432 0 1 3 5 1 2 4 6 |
但是,您可以轻松地创建该字典并将其包含在对
1 2 3 4 5 6 | # 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非唯一列
1 2 3 4 5 6 7 8 9 10 11 | 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使用
首先,请注意当我们尝试使用解决方案1时会发生什么:
1 2 3 4 5 | df.rename(columns=dict(zip(df, new))) y765 y765 z432 0 1 3 5 1 2 4 6 |
我们没有将
1 2 3 4 5 | pd.concat([c for _, c in df.items()], axis=1, keys=new) x098 y765 z432 0 1 3 5 1 2 4 6 |
解决方案3重建。只有在所有列都有单个
单根
1 2 3 4 5 | pd.DataFrame(df.values, df.index, new) x098 y765 z432 0 1 3 5 1 2 4 6 |
混合
1 2 3 4 5 | 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这是
单根
1 2 3 4 5 | df.T.set_index(np.asarray(new)).T x098 y765 z432 0 1 3 5 1 2 4 6 |
混合
1 2 3 4 5 | 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在
1 2 3 4 5 | df.rename(columns=lambda x, y=iter(new): next(y)) x098 y765 z432 0 1 3 5 1 2 4 6 |
正如sopython聊天室的人向我指出的,如果我在
1 2 3 4 5 | df.rename(columns=lambda x, *, y=iter(new): next(y)) x098 y765 z432 0 1 3 5 1 2 4 6 |
1 | df = pd.DataFrame({'$a': [1], '$b': [1], '$c': [1], '$d': [1], '$e': [1]}) |
如果新列列表与现有列的顺序相同,则分配很简单:
1 2 3 4 5 | new_cols = ['a', 'b', 'c', 'd', 'e'] df.columns = new_cols >>> df a b c d e 0 1 1 1 1 1 |
如果有一个字典将旧列名键入新列名,则可以执行以下操作:
1 2 3 4 5 | 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 |
如果没有列表或字典映射,则可以通过列表理解来删除前导的
1 | df.columns = [col[1:] if col[0] == '$' else col for col in df] |
如果有了数据帧,df.columns会将所有内容转储到一个可以操作的列表中,然后作为列的名称重新分配到数据帧中…
1 2 3 4 | 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的函数执行时间最快-虽然这些函数执行速度非常快,但我们比较了所有答案的0.000和0.001秒取整。道德:我上面的回答可能不是最好的方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | 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)') |
1 | df.rename(index=str,columns={'A':'a','B':'b'}) |
https://pandas.pydata.org/pandas-docs/stable/generated/pandas.dataframe.rename.html
另一种替换原始列标签的方法是从原始列标签中除去不需要的字符(这里是"$")。
这可以通过在df.columns上运行for循环并将剥离的列附加到df.columns来完成。
相反,我们可以使用下面的列表理解在一个语句中巧妙地做到这一点:
1 | df.columns = [col.strip('$') for col in df.columns] |
(python中的
我知道这个问题和答案已经被反复考虑过了。但我提到它是为了启发我遇到的一个问题。我能够用不同答案的零碎部分来解决这个问题,因此在任何人需要的时候提供我的响应。
我的方法是通用的,您可以通过逗号分隔
工作代码:
1 2 3 4 5 6 7 8 9 | 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 ] |
输出:
1 2 3 4 5 6 7 8 9 | >>> 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 |
您可以使用
1 | df.columns = df.columns.str.slice(1) |
真正的简单使用
1 | df.columns = ['Name1', 'Name2', 'Name3'...] |
它将按您输入的顺序分配列名称
注意,这些方法不适用于多索引。对于多索引,需要执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | >>> 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 |
另一个选项是使用正则表达式重命名:
1 2 3 4 5 6 7 8 9 10 | 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 |
重命名数据帧列并替换格式
1 2 3 4 5 6 7 8 9 10 11 12 | import pandas as pd data = {'year':[2015,2011,2007,2003,1999,1996,1992,1987,1983,1979,1975], 'team':['Australia','India','Australia','Australia','Australia','Sri Lanka','Pakistan','Australia','India','West Indies','West Indies'], } df = pd.DataFrame(data) #Rename Columns df.rename(columns={'year':'Years of Win','team':'Winning Team'}, inplace=True) #Replace format df = df.columns.str.replace(' ', '_') |
读取数据帧时重命名列:
1 2 3 4 5 6 | >>> df = pd.DataFrame({'$a': [1], '$b': [1], '$c': [1]}).rename(columns = {'$a' : 'a','$b':'b','$c':'c'}) Out[1]: a b c 0 1 1 1 |
导入有助于创建数据帧的库:
1 2 | import pandas as pd import numpy as np |
创建数据帧:
1 | df = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['a', 'b', 'c']) |
重命名数据帧:
1 | df.rename(columns={'a':'x', 'b':'y', 'c':'z'}, index=str) |
df.columns现在应该有不同的值
我看到3个简单的方法
输出:'$A'、'$B'、'$C'、'$D'、'$E']
1。
2。
三。
如果必须处理由不受控制的提供系统命名的列的负载,那么我提出了以下方法,它是通用方法和特定替换的组合。
我首先使用regex表达式从数据帧列名创建字典,以便丢弃列名的某些附录。然后,我向字典添加特定的替换,以命名核心列,正如后面在接收数据库中所预期的那样。
然后一次应用于数据帧。
1 2 3 4 5 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) |
如果您不想使用行名
试试这个。它对我有用
1 | df.rename(index=str, columns={"$a":"a","$b":"b","$c" :"c","$d" :"d","$e" :"e"}) |
这里有一个我喜欢用来减少打字的漂亮的小功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 |
下面是一个如何工作的示例:
1 2 3 4 5 6 7 8 9 10 11 12 | 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') |
1 2 3 4 | import pandas as pd df.columns = [['$a', '$b', '$c', '$d', '$e']] df.rename(columns = {'$a':'a','$b':'b','$c':'c','$d':'d','$e':'e'}) df.head() |
1 2 3 4 5 6 7 8 9 10 11 12 | import pandas as pd data = {'year':[2015,2011,2007,2003,1999,1996,1992,1987,1983,1979,1975], 'team':['Australia','India','Australia','Australia','Australia','Sri Lanka','Pakistan','Australia','India','West Indies','West Indies'], } df = pd.DataFrame(data) #Rename Columns df.rename(columns={'year':'Years of Win','team':'Winning Team'}, inplace=True) #Replace format df.columns = df.columns.str.replace(' ', '_') |
假设您可以使用正则表达式。此解决方案消除了使用regex进行手动编码的需要。
1 2 3 4 5 6 7 8 9 | 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 |