迭代合并pandas DataFrame时如何自定义重复列命名规则避免_x/_y重复?
问题描述
假设我在循环中迭代合并pandas DataFrame,但经过两三次迭代后pandas会出现重复列名的问题,以下是为了简化演示而不使用循环的迭代合并示例:
A= {'Name':['A','B','C'],'GPA':[4.0,3.80,3.70], 'School':['U','U','U'], 'Time':[22,26,30]} A1 = pd.DataFrame(A) B= {'Name':['D','E','F'],'GPA':[3.50,3.70,3.60], 'School':['S','S','S'],'Time':[34,44,54]} B1 = pd.DataFrame(B) C= {'Name':['G','H','I'],'GPA':[3.70,3.50,3.70], 'School':['C','C','C'],'Time':[76,86,96]} C1 = pd.DataFrame(C) L= [A1,B1,C1] comb = A1 for ii in L[1:]: comb = pd.concat([comb,ii],ignore_index=True) comb

B = pd.merge(comb, comb, on=['Name','GPA']) C = pd.merge(B, comb, on=['Name','GPA']) D = pd.merge(C, comb, on=['Name','GPA'])

可以看到Pandas会重复生成School_x、School_y这类名称,有没有办法可以将其设置为School_x、School_y、School_z、School_t这类不重复的名称?我指的不是合并完成后再重命名,而是强制merge操作时就为非合并键的重复列选择新名称,否则如果DataFrame有上千列,其中500个列名相同的话根本无法区分。
更新:以上只是示例,假设你是按照如下方式循环合并多个DataFrame:
for ii in list: df = df.merge(A,on = 'some column', how = 'outer')
这种情况下要怎么迭代修改列名?看起来每次合并时重复列哪怕带后缀也会出现重复的问题。
解决方案
pandas的merge方法默认仅提供两个固定后缀(_x、_y)处理重名列,多次迭代合并时必然会出现后缀重复的问题,没有内置参数可以自动生成连续后缀,可通过以下两种方式解决:
方案1:动态指定每次合并的后缀
循环迭代时按合并顺序生成唯一后缀,传入merge的suffixes参数即可。合并次数少可以用x/y/z这类字母后缀,合并次数多推荐用数字序号,辨识度更高:
import pandas as pd import string # 待合并的DataFrame列表 df_list = [df1, df2, df3, df4] # 合并键,可根据实际需求修改 merge_keys = ['Name', 'GPA'] # 生成后缀序列,如需数字后缀替换为 [f'_{i}' for i in range(1, len(df_list))] 即可 suffix_list = [''] + [f'_{c}' for c in string.ascii_lowercase[1:]] result = df_list[0] for idx, df in enumerate(df_list[1:], start=1): # 左表为已合并结果不需要加后缀,仅给右表的重名列加唯一后缀 result = result.merge(df, on=merge_keys, how='outer', suffixes=('', suffix_list[idx]))
方案2:合并前统一重命名非键列(更适合列数极多的场景)
提前给每个待合并DataFrame的非合并键列加上唯一标识后缀,从根源避免重名问题,后续也更容易对应列的来源:
df_list = [df1, df2, df3, df4] merge_keys = ['Name', 'GPA'] processed = [] for idx, df in enumerate(df_list): # 仅重命名非合并键的列 rename_dict = {col: f"{col}_{idx}" for col in df.columns if col not in merge_keys} processed.append(df.rename(columns=rename_dict)) # 合并时无重名列,不需要额外指定后缀 result = processed[0] for df in processed[1:]: result = result.merge(df, on=merge_keys, how='outer')
内容的提问来源于stack exchange,提问作者user59419
相关产品推荐
相关产品推荐

