如何基于含相似字符串的指定列合并两个Pandas DataFrame并保留重复值
嘿,我来帮你搞定这个合并的问题,分两部分解决:先处理重复值保留的合并,再搞定相似字符串的模糊匹配,最后给你通用的方法思路~
解决重复值保留的合并问题
首先,你之前遇到的“重复值”问题,其实pandas.merge()默认就会保留所有匹配的重复组合哦!比如如果df1里有2行kebele_name='A',df2里有3行kebele_name='A',合并后会生成2*3=6行对应记录,这就是保留重复值的效果。
如果之前报错,可能是你没指定合适的连接类型?给你调整后的代码:
import pandas as pd # 读取两个CSV文件 csv1 = pd.read_csv("combined_csv2.csv") csv2 = pd.read_csv("snnp.csv") # 合并时根据需求选择连接类型: # - how='inner':只保留两边都有的woreda_name+kebele_name组合(默认) # - how='outer':保留所有两边的行,没有匹配的用NaN填充 # - how='left':保留csv1的所有行,csv2没有匹配的用NaN填充 # - how='right':保留csv2的所有行,csv1没有匹配的用NaN填充 csv_out = csv1.merge(csv2, on=['woreda_name', 'kebele_name'], how='inner') # 保存结果,不要索引列 csv_out.to_csv("file_out11.csv", index=False)
这样就能确保所有重复的匹配都被保留下来啦~
处理相似字符串的模糊匹配合并
接下来是你提到的相似字符串(比如wosharba和woshamba)的匹配问题,这里有两种通用方法,根据你的场景选:
方法1:基于字符串相似度的模糊匹配(适合未知拼写差异)
这种方法用相似度算法(比如Levenshtein距离)自动找到最相似的字符串,推荐用rapidfuzz库(比老的fuzzywuzzy快很多)。
步骤如下:
- 先安装库:
pip install rapidfuzz - 给每个
kebele_name找到另一个DataFrame中最相似的匹配,再合并:
from rapidfuzz import process, fuzz import pandas as pd csv1 = pd.read_csv("combined_csv2.csv") csv2 = pd.read_csv("snnp.csv") # 提取csv2中所有唯一的kebele_name,用于匹配参考 kebele_reference = csv2['kebele_name'].unique().tolist() # 定义匹配函数:找到相似度超过阈值的最佳匹配(阈值可以自己调,比如80) def get_best_match(name, threshold=80): # WRatio能处理大小写、空格、部分拼写差异,适用性强 match_result = process.extractOne(name, kebele_reference, scorer=fuzz.WRatio) if match_result and match_result[1] >= threshold: return match_result[0] # 没有符合阈值的匹配就返回None return None # 给csv1添加匹配后的kebele_name列 csv1['matched_kebele'] = csv1['kebele_name'].apply(get_best_match) # 用匹配后的列和csv2合并,这里用left join保留csv1的所有行 csv_out = csv1.merge( csv2, left_on=['woreda_name', 'matched_kebele'], right_on=['woreda_name', 'kebele_name'], how='left' ) # 可以删掉临时的匹配列,或者保留看匹配情况 csv_out = csv_out.drop(columns=['matched_kebele']) # 保存结果 csv_out.to_csv("file_out_fuzzy.csv", index=False)
方法2:字符串标准化(适合已知拼写/格式差异)
如果你知道具体的拼写错误(比如sharba应该是shamba),或者只是大小写、空格这类格式问题,可以先标准化字符串再合并:
import pandas as pd # 定义标准化函数:统一格式,替换已知错误 def standardize_kebele(name): if pd.isna(name): return name # 转小写、去前后空格、替换空格为下划线(可选) standardized = name.strip().lower().replace(' ', '_') # 替换你知道的拼写错误 standardized = standardized.replace('sharba', 'shamba') # 可以加更多替换规则,比如其他常见错误 return standardized csv1 = pd.read_csv("combined_csv2.csv") csv2 = pd.read_csv("snnp.csv") # 给两个DF都添加标准化后的列 csv1['standardized_kebele'] = csv1['kebele_name'].apply(standardize_kebele) csv2['standardized_kebele'] = csv2['kebele_name'].apply(standardize_kebele) # 用标准化后的列合并,保留原列 csv_out = csv1.merge( csv2, on=['woreda_name', 'standardized_kebele'], how='inner' ) # 保存结果 csv_out.to_csv("file_out_standardized.csv", index=False)
通用合并流程总结
最后给你梳理一下处理这类问题的通用步骤:
- 第一步:确定合并的连接类型(inner/left/right/outer),确保
merge的how参数符合你的需求,这样就能自动保留重复值的匹配。 - 第二步:处理字符串差异:
- 已知格式/拼写错误 → 用字符串标准化方法;
- 未知的相似字符串 → 用模糊匹配方法(基于相似度算法)。
内容的提问来源于stack exchange,提问作者Desta Werash
相关产品推荐
相关产品推荐

