合并多个DataFrame后出现重复列,如何保留目标单列信息?
解决多CSV合并后重复列的问题
问题场景
- 主DataFrame包含邮编列表(列名:
LocationPostCode (72 blanks, 43 duplicates, 1477 uniques)) - 存在27个以
area0.csv至area26.csv命名的CSV文件,每个文件包含pcd(邮编)和ru11ind(区域信息)字段 - 原循环合并代码执行后,生成的结果出现多组
pcd和ru11ind重复列,需要合并为单一有效ru11ind列并删除pcd列
原代码问题分析
原代码每次循环都读取上一轮的结果文件做左连接,每次连接都会新增pcd和ru11ind列(pandas会自动给重复列名加后缀如_x、_y),最终导致列数越来越多。
改进方案
方案1:先合并所有区域文件(推荐,高效)
先将所有area CSV合并为一个去重的邮编-区域映射表,再与主表一次性合并,从根源避免重复列。
import pandas as pd import os # 读取主表数据 df_loc = pd.read_excel('C:/Users/User/Desktop/Lloyds Pharma/locations.xlsx') results_dir = 'C:/Users/User/Desktop/Lloyds Pharma/tmp_chunks/' area_files_dir = r'C:\Users\User\Desktop\Lloyds Pharma\tmp_chunks/' # 读取所有area CSV文件,仅保留需要的列 area_data_list = [] for filename in os.listdir(area_files_dir): # 只处理area开头的CSV文件,避免误读其他文件 if filename.startswith('area') and filename.endswith('.csv'): file_path = os.path.join(area_files_dir, filename) area_df = pd.read_csv(file_path, usecols=['pcd', 'ru11ind']) area_data_list.append(area_df) # 合并所有区域数据,对同一邮编去重(保留第一条有效记录) combined_area_df = pd.concat(area_data_list, ignore_index=True).drop_duplicates(subset='pcd', keep='first') # 主表与区域映射表合并 final_df = pd.merge( df_loc, combined_area_df, left_on='LocationPostCode (72 blanks, 43 duplicates, 1477 uniques)', right_on='pcd', how='left' ) # 删除多余的pcd列,保存结果 final_df = final_df.drop(columns=['pcd']) final_df.to_csv(os.path.join(results_dir, 'final_result.csv'), index=False)
方案2:循环合并时实时清理重复列(适合内存有限场景)
如果无法一次性加载所有area文件,可在每次循环合并后,用已有非空值填充新列,仅补充缺失数据,同时删除多余列。
import pandas as pd import os df_loc = pd.read_excel('C:/Users/User/Desktop/Lloyds Pharma/locations.xlsx') results_dir = 'C:/Users/User/Desktop/Lloyds Pharma/tmp_chunks/' area_files_dir = r'C:\Users\User\Desktop\Lloyds Pharma\tmp_chunks/' # 获取所有area文件列表 area_files = [f for f in os.listdir(area_files_dir) if os.path.isfile(os.path.join(area_files_dir, f))] # 初始化最终结果表为原主表 final_df = df_loc.copy() for filename in area_files: file_path = os.path.join(area_files_dir, filename) area_df = pd.read_csv(file_path, usecols=['pcd', 'ru11ind']) # 临时合并主表与当前area文件 temp_merge = pd.merge( final_df, area_df, left_on='LocationPostCode (72 blanks, 43 duplicates, 1477 uniques)', right_on='pcd', how='left' ) # 处理ru11ind列:保留已有非空值,用新数据填充空值 if 'ru11ind' in final_df.columns: final_df['ru11ind'] = final_df['ru11ind'].combine_first(temp_merge['ru11ind']) else: # 第一次合并,直接赋值 final_df['ru11ind'] = temp_merge['ru11ind'] # 删除临时生成的pcd列(忽略不存在的列) final_df = final_df.drop(columns=['pcd'], errors='ignore') # 保存最终结果 final_df.to_csv(os.path.join(results_dir, 'final_result.csv'), index=False)
关键改进点
- 方案1通过预合并区域数据并去重,只做一次表连接,彻底避免重复列生成
- 方案2使用
combine_first方法确保仅补充缺失的区域信息,同时实时清理多余的pcd列
内容的提问来源于stack exchange,提问作者EKreger
相关产品推荐
相关产品推荐

