我想从
['$a', '$b', '$c', '$d', '$e']
to
['a', 'b', 'c', 'd', 'e']
我想从
['$a', '$b', '$c', '$d', '$e']
to
['a', 'b', 'c', 'd', 'e']
当前回答
除了已经提供的解决方案之外,您还可以在读取文件时替换所有列。我们可以使用names和header=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)
在这种情况下,所有列名都将替换为列表中的名称。
其他回答
如果您必须处理由提供系统命名的超出您控制范围的列负载,我提出了以下方法,它是一种通用方法和特定替换方法的组合。
首先使用正则表达式从数据帧列名创建一个字典,以便丢弃列名的某些附加部分,然后向字典中添加特定替换项,以命名接收数据库中的核心列。
然后将其一次性应用于数据帧。
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)
许多panda函数都有一个就地参数。当设置为True时,转换将直接应用于调用它的数据帧。例如:
df = pd.DataFrame({'$a':[1,2], '$b': [3,4]})
df.rename(columns={'$a': 'a'}, inplace=True)
df.columns
>>> Index(['a', '$b'], dtype='object')
或者,在某些情况下,您希望保留原始数据帧。如果创建数据帧是一项昂贵的任务,我经常看到人们陷入这种情况。例如,如果创建数据帧需要查询雪花数据库。在这种情况下,只需确保将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')
如果这些类型的转换是您经常做的,那么您还可以研究一些不同的panda GUI工具。我是一个叫做水户的人的创造者。它是一个电子表格,可以自动将您的编辑转换为python代码。
列名与系列名称
我想解释一下幕后发生的事情。
数据帧是一组系列。
序列又是numpy.array的扩展。
numpy.arrays具有属性.name。
这是系列的名称。熊猫很少尊重这个属性,但它会在某些地方停留,可以用来攻击熊猫的一些行为。
命名列列表
这里有很多答案谈到df.columns属性是一个列表,而实际上它是一个系列。这意味着它具有.name属性。
如果您决定填写列的名称“系列:
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
请注意,索引的名称总是低一列。
挥之不去的艺术事实
.name属性有时会持续存在。如果将df.columns设置为['one','two'],则df.one.name将为'one'。
如果您将df.one.name设置为'three',则df.columns仍然会给您['one','two'],df.one.name会给您'three]。
BUT
pd.DataFrame(df.one)将返回
three
0 1
1 2
2 3
因为Pandas重用已经定义的Series的.name。
多级列名
Pandas有多种方法来实现多层列名。这里面没有太多魔法,但我想在我的回答中也包括这一点,因为我没有看到任何人在这里学习这一点。
|one |
|one |two |
0 | 4 | 1 |
1 | 5 | 2 |
2 | 6 | 3 |
通过将列设置为列表,这很容易实现,如下所示:
df.columns = [['one', 'one'], ['one', 'two']]
我的单线回答是
df.columns=df_new_cols
它是最好的,处理时间为1/3。
timeit比较:
df有七列。我正在尝试更改一些名称。
%timeit df.rename(columns={old_col:new_col for (old_col,new_col) in zip(df_old_cols,df_new_cols)},inplace=True)
214 µs ± 10.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit df.rename(columns=dict(zip(df_old_cols,df_new_cols)),inplace=True)
212 µs ± 7.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit df.columns = df_new_cols
72.9 µs ± 17.2 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
我的方法是通用的,您可以通过逗号分隔分隔符=variable来添加额外的分隔符,并对其进行未来验证。
工作代码:
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 ]
输出:
>>> 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