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

时间:2016-11-23 21:57:04

标签: python pandas

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

In [77]: X_R
Out[77]: 
       Retail   Cost
   0   0.7085   0.5000

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

X_R.rename(index=str, columns={"dollars": "Retail", "dollars": "Cost"})

使用Pandas重命名功能可以实现'工作:

int main(){
   int n; //size
   int k; //number of rotations
   int a_i; //index
   scanf("%d %d",&n,&k);
   int *a = malloc(sizeof(int) * n); //input array
   for(a_i = 0; a_i <= n; a_i++){
      scanf("%d",&a[a_i]);
   }

int temp;
for(a_i = 0; a_i <= k; a_i++){
    temp = a[0];
    for(a_i = 0; a_i < n-1; a_i++) {
        a[a_i] = a[a_i+1];
    }
    a[a_i] = temp;   
}

for(a_i = 0; a_i < n; a_i++){
    printf("%d ", a[a_i]);
}


return 0;
}

给我两个名为Cost的列。

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

5 个答案:

答案 0 :(得分: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

答案 1 :(得分:5)

X_R.columns = ['Retail','Cost']

答案 2 :(得分:5)

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

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

答案 3 :(得分:3)

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

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

import pandas as pd
from collections import defaultdict

renamer = defaultdict()

我们遍历重复的列名以创建一个字典,其中的键是重复的列名,而值是新列名的列表。我选择此列表为原始名称_0,原始名称_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']})

原始数据框:

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

通过从重命名器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

(作为一个旁注,一些人质疑为什么首先要存在重复的列名。对于我自己,我在使用xlwings程序包导入时遇到了重复的列名(以处理受密码保护的Excel文件)。您也可能会由于疏忽使用pd.concat创建重复的列名。

答案 4 :(得分:3)

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

# A dataframe with duplicated column names
df = pd.DataFrame([[1, 2, 3],
                   [4, 5, 6],
                   [7, 8, 9]])
df.columns = ['a', 'b', 'b']

# Columns to not rename
excluded = df.columns[~df.columns.duplicated(keep=False)]

# An incrementer
import itertools
inc = itertools.count().__next__

# A renamer
def ren(name):
    return f"{name}{inc()}" if name not in excluded else name

# Use inside rename()
df.rename(columns=ren)

    a   b   b              a  b0  b1
0   1   2   3          0   1   2   3
1   4   5   6    =>    1   4   5   6
2   7   8   8          2   7   8   9