如何在Python中不使用Pandas实现Full Outer Join?(已有Inner Join代码)
实现无Pandas的Full Outer Join
要实现Full Outer Join,需要覆盖三种情况:两个文件中都存在的键、仅第一个文件存在的键、仅第二个文件存在的键。以下是基于你现有Inner Join代码修改后的实现:
修改后的代码
import collections import csv import sys def c_merge(f1, f2): # 读取第一个文件并构建字典 with open(f1, 'r') as infile: obj = csv.reader(infile) header_a = next(obj) dict_a = {row[0]: row[1:] for row in obj} # 读取第二个文件并构建字典(支持同一键多行) with open(f2, 'r') as infile: obj = csv.reader(infile) header_b = next(obj) dict_b = collections.defaultdict(list) for row in obj: dict_b[row[0]].append(row[1:]) # 获取所有唯一键(Full Outer Join需要包含所有键) all_keys = set(dict_a.keys()).union(dict_b.keys()) with open('newfile.txt', 'w') as newfile: w = csv.writer(newfile) # 写入合并后的表头 w.writerow(header_a + header_b[1:]) for key in all_keys: # 情况1:键同时存在于两个文件(Inner Join逻辑) if key in dict_a and key in dict_b: for b_row in dict_b[key]: w.writerow([key] + dict_a[key] + b_row) # 情况2:键仅存在于第一个文件,补全第二个文件的空列 elif key in dict_a: empty_cols = [''] * (len(header_b) - 1) w.writerow([key] + dict_a[key] + empty_cols) # 情况3:键仅存在于第二个文件,补全第一个文件的空列 else: empty_cols = [''] * (len(header_a) - 1) for b_row in dict_b[key]: w.writerow([key] + empty_cols + b_row) if __name__ == "__main__": # 修复命令行参数:sys.argv[0]是脚本名,应取第1和第2个参数 if len(sys.argv) != 3: print("用法: python script.py 文件1.csv 文件2.csv") sys.exit(1) c_merge(sys.argv[1], sys.argv[2]) # 打印结果 with open('newfile.txt', 'r') as f: obj = csv.reader(f) for x in obj: print(x)
关键修改说明
- 收集所有键:通过
set(dict_a.keys()).union(dict_b.keys())获取两个文件的所有唯一键,确保不会遗漏任何行。 - 三种场景处理:
- 共同键:沿用原Inner Join的逻辑,合并对应行。
- 仅第一个文件的键:用空字符串填充第二个文件的所有列。
- 仅第二个文件的键:用空字符串填充第一个文件的所有列,同时处理第二个文件中同一键的多行数据。
- 修复参数错误:原代码中
sys.argv[0]是脚本本身,改为sys.argv[1]和sys.argv[2]作为输入文件路径,并增加参数校验。
内容的提问来源于stack exchange,提问作者khaledElgohary
相关产品推荐
相关产品推荐

