重命名数据片切片上的列无法按预期执行

时间:2019-05-24 13:11:07

标签: python pandas dataframe

我试图清除数据框中的列名,但仅清除部分列。

当尝试以某种方式替换数据框切片上的列名称时,它不起作用,为什么?

可以说我们有以下数据框:
注意,底部是可复制的代码以重现数据:

   Value ColAfjkj ColBhuqwa ColCouiqw
0      1        a         e         i
1      2        b         f         j
2      3        c         g         k
3      4        d         h         l

我想清理列名(预期输出):

   Value ColA ColB ColC
0      1    a    e    i
1      2    b    f    j
2      3    c    g    k
3      4    d    h    l

方法1

我可以这样获得干净的列名:

df.iloc[:, 1:].columns.str[:4]

Index(['ColA', 'ColB', 'ColC'], dtype='object')

方法2

s = df.iloc[:, 1:].columns
[col[:4] for col in s]

['ColA', 'ColB', 'ColC']

但是,当我尝试覆盖列名时,什么也没发生:

df.iloc[:, 1:].columns = df.iloc[:, 1:].columns.str[:4]

   Value ColAfjkj ColBhuqwa ColCouiqw
0      1        a         e         i
1      2        b         f         j
2      3        c         g         k
3      4        d         h         l

与第二种方法相同:

s = df.iloc[:, 1:].columns
cols = [col[:4] for col in s]

df.iloc[:, 1:].columns = cols

   Value ColAfjkj ColBhuqwa ColCouiqw
0      1        a         e         i
1      2        b         f         j
2      3        c         g         k
3      4        d         h         l

这确实有效,但是您必须手动连接第一列的名称,这并不理想:

df.columns = ['Value'] + df.iloc[:, 1:].columns.str[:4].tolist()

   Value ColA ColB ColC
0      1    a    e    i
1      2    b    f    j
2      3    c    g    k
3      4    d    h    l

有没有更简单的方法来实现这一目标?我想念什么吗?


要复制的数据帧:

df = pd.DataFrame({'Value':[1,2,3,4],
                   'ColAfjkj':['a', 'b', 'c', 'd'],
                   'ColBhuqwa':['e', 'f', 'g', 'h'],
                   'ColCouiqw':['i', 'j', 'k', 'l']})

3 个答案:

答案 0 :(得分:2)

这是因为熊猫的索引是不可变的。如果您查看class pandas.Index的文档,则会看到它的定义为:

  

不可变的ndarray实现有序的,可切片的集合

因此,要对其进行修改,您必须创建一个新的列名列表,例如:

df.columns = [df.columns[0]] + list(df.iloc[:, 1:].columns.str[:4])

另一种选择是将rename与包含要替换的列的字典一起使用:

df.rename(columns=dict(zip(df.columns[1:], df.columns[1:].str[:4])))

答案 1 :(得分:2)

我也遇到了这个问题,并提出了以下解决方案:

首先,为要重命名的列创建一个掩码

mask = df.iloc[:,1:4].columns

然后,使用列表推导和条件式仅重命名所需的列

df.columns = [x if x not in mask else str[:4] for x in df.columns]

答案 2 :(得分:1)

要覆盖列名,可以使用.rename()方法:

因此,它看起来像:

df.rename(columns={'ColA_fjkj':'ColA',
                   'ColB_huqwa':'ColB',
                   'ColC_ouiqw':'ColC'}
          , inplace=True)

有关重命名的更多信息,请参见文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.rename.html