我在df中有几个相同的列。需要重命名它们。通常的重命名重命名全部 无论如何,我可以将下面的blah(s)重命名为blah1,blah4,blah5?
In [6]:
df=pd.DataFrame(np.arange(2*5).reshape(2,5))
df.columns=['blah','blah2','blah3','blah','blah']
df
Out[6]:
blah blah2 blah3 blah blah
0 0 1 2 3 4
1 5 6 7 8 9
在[7]中:
df.rename(columns = {'blah':'blah1'})
Out[7]:
blah1 blah2 blah3 blah1 blah1
0 0 1 2 3 4
1 5 6 7 8 9
答案 0 :(得分:13)
我希望在Pandas中找到一个解决方案而不是一般的Python解决方案。 如果列的get_loc()函数找到重复项,并且“True”值指向找到重复项的位置,则它返回一个屏蔽数组。然后我使用掩码为这些位置分配新值。在我的情况下,我提前知道我将获得多少重复以及我将要分配给他们但是看起来df.columns.get_duplicates()会返回所有重复的列表然后你可以如果您需要更通用的重复除草操作,请将该列表与get_loc()结合使用
cols=pd.Series(df.columns)
for dup in df.columns.get_duplicates(): cols[df.columns.get_loc(dup)]=[dup+'.'+str(d_idx) if d_idx!=0 else dup for d_idx in range(df.columns.get_loc(dup).sum())]
df.columns=cols
blah blah2 blah3 blah.1 blah.2
0 0 1 2 3 4
1 5 6 7 8 9
答案 1 :(得分:11)
Starting with Pandas 0.19.0 pd.read_csv()
has improved support for duplicate column names
所以我们可以尝试使用内部方法:
GetData2
这是“魔术”功能:
In [137]: pd.io.parsers.ParserBase({'names':df.columns})._maybe_dedup_names(df.columns)
Out[137]: ['blah', 'blah2', 'blah3', 'blah.1', 'blah.2']
答案 2 :(得分:7)
你可以用这个:
def df_column_uniquify(df):
df_columns = df.columns
new_columns = []
for item in df_columns:
counter = 0
newitem = item
while newitem in new_columns:
counter += 1
newitem = "{}_{}".format(item, counter)
new_columns.append(newitem)
df.columns = new_columns
return df
然后
import numpy as np
import pandas as pd
df=pd.DataFrame(np.arange(2*5).reshape(2,5))
df.columns=['blah','blah2','blah3','blah','blah']
以便 df :
blah blah2 blah3 blah blah
0 0 1 2 3 4
1 5 6 7 8 9
然后
df = df_column_uniquify(df)
以便 df :
blah blah2 blah3 blah_1 blah_2
0 0 1 2 3 4
1 5 6 7 8 9
答案 3 :(得分:3)
duplicated_idx = dataset.columns.duplicated()
duplicated = dataset.columns[duplicated_idx].unique()
rename_cols = []
i = 1
for col in dataset.columns:
if col in duplicated:
rename_cols.extend([col + '_' + str(i)])
else:
rename_cols.extend([col])
dataset.columns = rename_cols
答案 4 :(得分:2)
您可以直接指定列:
In [12]:
df.columns = ['blah','blah2','blah3','blah4','blah5']
df
Out[12]:
blah blah2 blah3 blah4 blah5
0 0 1 2 3 4
1 5 6 7 8 9
[2 rows x 5 columns]
如果您想动态重命名重复列,那么您可以执行以下操作(代码来自答案2:Index of duplicates items in a python list):
In [25]:
import collections
dups = collections.defaultdict(list)
dup_indices=[]
col_list=list(df.columns)
for i, e in enumerate(list(df.columns)):
dups[e].append(i)
for k, v in sorted(dups.items()):
if len(v) >= 2:
dup_indices = v
for i in dup_indices:
col_list[i] = col_list[i] + ' ' + str(i)
col_list
Out[25]:
['blah 0', 'blah2', 'blah3', 'blah 3', 'blah 4']
然后您可以使用它来分配回来,您还可以使用一个函数来生成在重命名之前列中不存在的唯一名称。
答案 5 :(得分:1)
这是一种适用于多索引的解决方案
# Take a df and rename duplicate columns by appending number suffixes
def rename_duplicates(df):
import copy
new_columns = df.columns.values
suffix = {key: 2 for key in set(new_columns)}
dup = pd.Series(new_columns).duplicated()
if type(df.columns) == pd.core.indexes.multi.MultiIndex:
# Need to be mutable, make it list instead of tuples
for i in range(len(new_columns)):
new_columns[i] = list(new_columns[i])
for ix, item in enumerate(new_columns):
item_orig = copy.copy(item)
if dup[ix]:
for level in range(len(new_columns[ix])):
new_columns[ix][level] = new_columns[ix][level] + f"_{suffix[tuple(item_orig)]}"
suffix[tuple(item_orig)] += 1
for i in range(len(new_columns)):
new_columns[i] = tuple(new_columns[i])
df.columns = pd.MultiIndex.from_tuples(new_columns)
# Not a MultiIndex
else:
for ix, item in enumerate(new_columns):
if dup[ix]:
new_columns[ix] = item + f"_{suffix[item]}"
suffix[item] += 1
df.columns = new_columns
答案 6 :(得分:0)
由于接受的答案(由Lamakaha提出)不适用于最新版本的熊猫,并且由于其他建议看起来有些笨拙,因此我制定了自己的解决方案:
def dedupIndex(idx, fmt=None, ignoreFirst=True):
# fmt: A string format that receives two arguments:
# name and a counter. By default: fmt='%s.%03d'
# ignoreFirst: Disable/enable postfixing of first element.
idx = pd.Series(idx)
duplicates = idx[idx.duplicated()].unique()
fmt = '%s.%03d' if fmt is None else fmt
for name in duplicates:
dups = idx==name
ret = [ fmt%(name,i) if (i!=0 or not ignoreFirst) else name
for i in range(dups.sum()) ]
idx.loc[dups] = ret
return pd.Index(idx)
使用以下功能:
df.columns = dedupIndex(df.columns)
# Result: ['blah', 'blah2', 'blah3', 'blah.001', 'blah.002']
df.columns = dedupIndex(df.columns, fmt='%s #%d', ignoreFirst=False)
# Result: ['blah #0', 'blah2', 'blah3', 'blah #1', 'blah #2']
答案 7 :(得分:0)
感谢@Lamakaha提供解决方案。您的想法使我有机会对其进行修改并使其在所有情况下均可行。
我正在使用Python 3.7.3版本。
我在您的数据集上尝试了您的一段代码,该数据集只有一个重复的列,即两个具有相同名称的列。不幸的是,列名保持原样,没有重命名。最重要的是,我警告说"get_duplicates()
已过时,并将在以后的版本中删除。”我使用duplicated()
和unique()
代替get_duplicates()
,无法产生预期的结果。
我已经稍微修改了您的代码段,现在对我的数据集以及其他一般情况下的代码都适用。
以下是在问题中提到的示例数据集上对代码进行修改和未修改的代码以及结果:
df=pd.DataFrame(np.arange(2*5).reshape(2,5))
df.columns=['blah','blah2','blah3','blah','blah']
df
cols=pd.Series(df.columns)
for dup in df.columns.get_duplicates():
cols[df.columns.get_loc(dup)]=[dup+'.'+str(d_idx) if d_idx!=0 else dup for d_idx in range(df.columns.get_loc(dup).sum())]
df.columns=cols
df
f:\ Anaconda3 \ lib \ site-packages \ ipykernel_launcher.py:2:FutureWarning: “ get_duplicates”已弃用,以后将被删除 发布。您可以改用idx [idx.duplicated()]。unique()
输出:
blah blah2 blah3 blah blah.1
0 0 1 2 3 4
1 5 6 7 8 9
三个“ blah”中的两个未正确重命名。
df=pd.DataFrame(np.arange(2*5).reshape(2,5))
df.columns=['blah','blah2','blah3','blah','blah']
df
cols=pd.Series(df.columns)
for dup in cols[cols.duplicated()].unique():
cols[cols[cols == dup].index.values.tolist()] = [dup + '.' + str(i) if i != 0 else dup for i in range(sum(cols == dup))]
df.columns=cols
df
输出:
blah blah2 blah3 blah.1 blah.2
0 0 1 2 3 4
1 5 6 7 8 9
这是在另一个示例上运行的修改后的代码:
cols = pd.Series(['X', 'Y', 'Z', 'A', 'B', 'C', 'A', 'A', 'L', 'M', 'A', 'Y', 'M'])
for dup in cols[cols.duplicated()].unique():
cols[cols[cols == dup].index.values.tolist()] = [dup + '_' + str(i) if i != 0 else dup for i in range(sum(cols == dup))]
cols
Output:
0 X
1 Y
2 Z
3 A
4 B
5 C
6 A_1
7 A_2
8 L
9 M
10 A_3
11 Y_1
12 M_1
dtype: object
希望这对寻求上述问题答案的人有所帮助。
答案 8 :(得分:0)
使用一些测试创建了一个函数,因此应该将其放置好;这与Lamakaha's excellent solution有点不同,因为它重命名了重复列的首次出现:
this.get('username')
答案 9 :(得分:0)
我们可以为每个列分配一个不同的名称。
支持重复的列名就像= [a,b,c,d,d,c]
然后仅创建要分配的名称列表:
C = [a,b,c,d,D1,C1]
df.columns = c
这对我有用。
答案 10 :(得分:0)
我刚刚写了这段代码,它使用列表理解来更新所有重复的名称。
df.columns = [x[1] if x[1] not in df.columns[:x[0]] else f"{x[1]}_{list(df.columns[:x[0]]).count(x[1])}" for x in enumerate(df.columns)]