Python中基于指定列合并两个CSV并去重(无中间文件)
内存中合并两个CSV并基于第二列去重的实现方案
核心思路
不需要生成中间文件的关键是:把两个CSV的内容全部在内存中处理,用一个集合记录已经出现过的第二列值,只保留未重复的行,最后直接写入目标文件。下面提供两种常见的实现方式:
方式一:使用Python原生csv模块(低内存占用,适合大文件)
这种方式逐行读取文件,不会一次性加载全部内容到内存,更适合处理超大CSV文件:
import csv def merge_deduplicate_csv(csv1_path, csv2_path, output_path): # 用集合存储已出现过的第二列值,确保唯一性 seen_keys = set() result_rows = [] # 处理第一个CSV:保留表头和所有唯一行 with open(csv1_path, 'r', newline='', encoding='utf-8') as f: reader = csv.reader(f) # 读取表头并加入结果 header = next(reader) result_rows.append(header) for row in reader: # 确保行有至少两列数据 if len(row) >= 2: key = row[1] if key not in seen_keys: seen_keys.add(key) result_rows.append(row) # 处理第二个CSV:只添加未出现过的行 with open(csv2_path, 'r', newline='', encoding='utf-8') as f: reader = csv.reader(f) # 跳过第二个CSV的表头 next(reader) for row in reader: if len(row) >= 2: key = row[1] if key not in seen_keys: seen_keys.add(key) result_rows.append(row) # 将结果写入目标文件 with open(output_path, 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f) writer.writerows(result_rows) # 调用示例 merge_deduplicate_csv("file1.csv", "file2.csv", "merged_result.csv")
关键点说明
seen_keys集合用来快速判断第二列值是否重复,查询效率远高于列表- 先处理第一个CSV的所有行,再处理第二个CSV,确保优先保留第一个文件中的数据
- 全程逐行处理,内存占用仅取决于结果集的大小,不会加载整个原文件
方式二:使用Pandas库(代码简洁,适合中小文件)
如果你的CSV文件不大,用Pandas可以用更少的代码完成需求:
import pandas as pd def merge_deduplicate_pandas(csv1_path, csv2_path, output_path): # 读取两个CSV到内存中的DataFrame df1 = pd.read_csv(csv1_path) df2 = pd.read_csv(csv2_path) # 合并两个DataFrame merged_df = pd.concat([df1, df2], ignore_index=True) # 基于第二列去重,保留首次出现的行 # 注意:如果第二列有明确列名,把`merged_df.columns[1]`替换成列名字符串,比如"user_id" deduplicated_df = merged_df.drop_duplicates(subset=merged_df.columns[1], keep="first") # 写入结果文件,不保留索引列 deduplicated_df.to_csv(output_path, index=False) # 调用示例 merge_deduplicate_pandas("file1.csv", "file2.csv", "merged_result.csv")
关键点说明
pd.concat直接在内存中合并两个DataFramedrop_duplicates方法可以直接指定去重的列,keep="first"表示保留第一次出现的行,换成keep="last"则保留最后一次出现的- 代码更简洁,但会把整个CSV加载到内存,不适合超大文件
注意事项
- 确保两个CSV的表头完全一致,否则合并后列会混乱
- 如果CSV文件编码不是UTF-8,需要修改
encoding参数(比如GBK编码改成encoding="gbk") - 若第二列可能存在空值,需要根据需求决定是否保留空值行
内容的提问来源于stack exchange,提问作者James Black
相关产品推荐
相关产品推荐

