使用重复的列名重命名Pandas数据框中的列?

Ale*_*man 6 python pandas

我有一个带有重复名称的列的df X:

In [77]: X_R
Out[77]: 
      dollars  dollars
   0   0.7085   0.5000
Run Code Online (Sandbox Code Playgroud)

我想重命名它,以便我有:

In [77]: X_R
Out[77]: 
       Retail   Cost
   0   0.7085   0.5000
Run Code Online (Sandbox Code Playgroud)

使用Pandas重命名功能确实有效:

X_R.rename(index=str, columns={"dollars": "Retail", "dollars": "Cost"})
Run Code Online (Sandbox Code Playgroud)

给我两个名为Cost的列.

在这种情况下,如何重命名列?

Max*_*axU 8

这是一个动态的解决方案:

In [59]: df
Out[59]:
   a  x  x  x  z
0  6  2  7  7  8
1  6  6  3  1  1
2  6  6  7  5  6
3  8  3  6  1  8
4  5  7  5  3  0

In [60]: d
Out[60]: {'x': ['x1', 'x2', 'x3']}

In [61]: df.rename(columns=lambda c: d[c].pop(0) if c in d.keys() else c)
Out[61]:
   a  x1  x2  x3  z
0  6   2   7   7  8
1  6   6   3   1  1
2  6   6   7   5  6
3  8   3   6   1  8
4  5   7   5   3  0
Run Code Online (Sandbox Code Playgroud)


gbt*_*mon 8

这是另一个我认为更好的动态解决方案

In [59]: df
Out[59]:
   a  x  x  x  z
0  6  2  7  7  8
1  6  6  3  1  1
2  6  6  7  5  6
3  8  3  6  1  8
4  5  7  5  3  0
In [61]: class renamer():
             def __init__(self):
                  self.d = dict()

              def __call__(self, x):
                  if x not in self.d:
                      self.d[x] = 0
                      return x
                  else:
                      self.d[x] += 1
                      return "%s_%d" % (x, self.d[x])

          df.rename(columns=renamer())
Out[61]:
   a  x  x_1  x_2  z
0  6   2   7   7  8
1  6   6   3   1  1
2  6   6   7   5  6
3  8   3   6   1  8
4  5   7   5   3  0
Run Code Online (Sandbox Code Playgroud)


小智 7

不是直接的答案,但由于这是一个顶级搜索结果,因此这里有一个简短而灵活的解决方案,可以将后缀附加到重复的列名称:

\n
# A dataframe with duplicated column names\ndf = pd.DataFrame([[1, 2, 3],\n                   [4, 5, 6],\n                   [7, 8, 9]])\ndf.columns = ['a', 'b', 'b']\n\n# Columns to not rename\nexcluded = df.columns[~df.columns.duplicated(keep=False)]\n\n# An incrementer\nimport itertools\ninc = itertools.count().__next__\n\n# A renamer\ndef ren(name):\n    return f"{name}{inc()}" if name not in excluded else name\n\n# Use inside rename()\ndf.rename(columns=ren)\n
Run Code Online (Sandbox Code Playgroud)\n

\xc2\xa0

\n
    a   b   b              a  b0  b1\n0   1   2   3          0   1   2   3\n1   4   5   6    =>    1   4   5   6\n2   7   8   8          2   7   8   9\n
Run Code Online (Sandbox Code Playgroud)\n


小智 6

X_R.columns = ['Retail','Cost']
Run Code Online (Sandbox Code Playgroud)


Ben*_*njw 5

MaxU的回答帮助我解决了同样的问题。在这个答案中,我添加了一种方法来查找那些重复的列标题。

首先,我们创建一个重复列名的字典,其中的值与所需的新列名相对应。为此,需要defaultdict子类。

import pandas as pd
from collections import defaultdict

renamer = defaultdict()
Run Code Online (Sandbox Code Playgroud)

我们迭代重复的列名以创建一个字典,其中键是重复的列名,值是新列名的列表。我选择这个列表为original name_0、original name_1,等等。

for column_name in df.columns[df.columns.duplicated(keep=False)].tolist():
    if column_name not in renamer:
        renamer[column_name] = [column_name+'_0']
    else:
        renamer[column_name].append(column_name +'_'+str(len(renamer[column_name])))

print(renamer)
defaultdict(None, {'b': ['b_0', 'b_1', 'b_2', 'b_3'], 'c': ['c_0', 'c_1']})
Run Code Online (Sandbox Code Playgroud)

原始数据框:

print(df)
        a   b   b   b   b   c   c   d
Item 0  2   1   0   2   8   3   9   5
Item 1  3   2   7   3   5   4   6   2
Item 2  4   3   8   1   5   7   4   4
Item 3  5   5   3   6   0   5   2   5
Run Code Online (Sandbox Code Playgroud)

通过从我们的重命名器 defaultdict 中分配新名称来重命名重复的列,保留不重复的列

df.rename(
    columns=lambda column_name: renamer[column_name].pop(0)
    if column_name in renamer 
    else column_name
)
        a   b_0 b_1 b_2 b_3 c_0 c_1 d
Item 0  2   1   0   2   8   3   9   5
Item 1  3   2   7   3   5   4   6   2
Item 2  4   3   8   1   5   7   4   4
Item 3  5   5   3   6   0   5   2   5
Run Code Online (Sandbox Code Playgroud)

(作为旁注,有几个人质疑为什么首先存在重复的列名。就我自己而言,我在使用 xlwings 包导入时遇到了重复的列名以处理受密码保护的 Excel 文件)。您也可能会无意中遇到重复的列名使用 来创建重复的列名pd.concat