如何迭代重命名Pandas数据框中的重复列(normal、KIRC)
处理Pandas重名列时的KeyError问题
问题描述
需要将Pandas数据框中的重名列normal和KIRC分别重命名为normal_1、normal_2、KIRC_1、KIRC_2,但运行代码时出现KeyError: 'KIRC'报错。
原代码
import pandas as pd gene_exp.columns = gene_exp.iloc[-1] gene_exp = gene_exp.iloc[:-1] gene_exp # Append "_[number]" c = pd.Series(gene_exp.columns) for dup in gene_exp.columns[gene_exp.columns.duplicated(keep=False)]: c[df.columns.get_loc(dup)] = ([dup + '_' + str(d_idx) if d_idx != 0 else dup for d_idx in range(gene_exp.columns.get_loc(dup).sum())] ) gene_exp
报错信息
KeyError: 'KIRC'
示例数据
| Gene | NAME | KIRC | normal | normal | KIRC | |
|---|---|---|---|---|---|---|
| 0 | ABC | DEF | GHI | JKL | MNO | PQR |
| 1 | STU | VWX | YZ | ABC | DEF | GHI |
期望输出
| Gene | NAME | KIRC_1 | normal_1 | normal_2 | KIRC_2 | |
|---|---|---|---|---|---|---|
| 0 | ABC | DEF | GHI | JKL | MNO | PQR |
| 1 | STU | VWX | YZ | ABC | DEF | GHI |
错误原因分析
- 变量名混淆:代码中使用了未定义的
df变量,实际数据框名为gene_exp,调用df.columns.get_loc(dup)直接触发KeyError。 get_loc用法错误:对于重复列,get_loc返回的是布尔数组而非单个索引位置,无法直接用于赋值操作。- 计数逻辑错误:
range(gene_exp.columns.get_loc(dup).sum())的逻辑不成立,布尔数组求和得到的是重复次数,但生成的列表长度与实际列位置数量不匹配,导致赋值失败。
解决方案
方法一:利用groupby+cumcount快速处理
这种方法简洁高效,适合批量处理重名列:
import pandas as pd # 构造示例数据(已有数据可跳过此步) data = { 'Gene': ['ABC', 'STU'], 'NAME': ['DEF', 'VWX'], 'KIRC': ['GHI', 'YZ'], 'normal': ['JKL', 'ABC'], 'normal': ['MNO', 'DEF'], 'KIRC': ['PQR', 'GHI'] } gene_exp = pd.DataFrame(data) # 生成新列名 cols = gene_exp.columns # 对每个列名按出现顺序生成递增序号(从1开始) seq = cols.groupby(cols).cumcount().add(1).astype(str) # 拼接列名与序号,非重复列保留原名 new_cols = cols.where(~cols.duplicated(keep=False), cols + '_' + seq) # 替换原列名 gene_exp.columns = new_cols print(gene_exp)
方法二:手动遍历计数
适合需要更精细控制的场景:
import pandas as pd # 构造示例数据(已有数据可跳过此步) data = { 'Gene': ['ABC', 'STU'], 'NAME': ['DEF', 'VWX'], 'KIRC': ['GHI', 'YZ'], 'normal': ['JKL', 'ABC'], 'normal': ['MNO', 'DEF'], 'KIRC': ['PQR', 'GHI'] } gene_exp = pd.DataFrame(data) counts = {} new_cols = [] column_list = gene_exp.columns.tolist() for col in column_list: # 记录当前列名的出现次数 counts[col] = counts.get(col, 0) + 1 # 如果是重复列,拼接序号;非重复列直接保留 if column_list.count(col) > 1: new_cols.append(f"{col}_{counts[col]}") else: new_cols.append(col) # 替换原列名 gene_exp.columns = new_cols print(gene_exp)
两种方法都能得到符合期望的输出,解决重名列的命名问题,同时避免原代码中的KeyError。
内容的提问来源于stack exchange,提问作者melolilili
相关产品推荐
相关产品推荐

