【问题标题】:Renaming columns on slice of dataframe not performing as expected重命名数据帧切片上的列未按预期执行
【发布时间】:2019-05-24 13:11:07
【问题描述】:

我试图清理数据框中的列名,但只清理了一部分列。

尝试以某种方式替换数据帧切片上的列名时不起作用,这是为什么呢?

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

   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

方法一

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

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']})

【问题讨论】:

  • 我认为这行得通.. df.columns = [d.split('_')[0] for d in df.columns] ?
  • df.columns = df.columns.str.split('_').str[0] ..?
  • 感谢@ChrisA 的建议,但它更多的是关于字符串切片,下划线不是一个很好的例子。我编辑了我的问题

标签: python pandas dataframe


【解决方案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

【讨论】:

  • 是的,感谢您的建议,这可行,但关键是不要手动输入名称。当您拥有 30 多个列时,工作量会很大
【解决方案2】:

这是因为 pandas 的索引是不可变的。如果您查看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])))

【讨论】:

  • 所以结论是我的解决方案是解决这个问题的最佳方法吗?
  • 是的,你的最后一种方法是@Erfan
  • df.columns = df.columns.str.split('_').str[0] :)
  • 第一个数据框不是一个很好的例子。我编辑了我的答案,查看新的数据框@jezrael
  • 应该不错,:) 但不是
【解决方案3】:

我也遇到了这个问题,想出了这个解决方案:

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

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

然后,使用列表推导和条件来重命名您想要的列

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-27
    • 2017-05-05
    • 1970-01-01
    • 2021-12-07
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    相关资源
    最近更新 更多