如何用FuzzyWuzzy在Python中匹配合并含相似姓名的Excel数据集
解决方案:标准化姓名后合并数据集
针对姓名存在标点、拼写、空格不一致的情况,核心思路是先标准化所有数据集的姓名列,生成统一的匹配键,再进行合并。以下是两种最优实现方案,根据你的实际场景选择:
方案一:固定变体映射(适合已知姓名差异)
如果姓名的差异是可预见的固定变体(比如缩写、拼写错误、标点差异),直接用字典映射+清洗的方式,速度快且匹配精准。
步骤1:读取并准备数据
import pandas as pd # 示例数据,实际替换为pd.read_excel('你的文件路径.xlsx') df_age = pd.DataFrame({ 'NAME': ['Jason Kai', 'George Jameson', 'Michael C. Henry', 'Max Jones', 'Tom Reyes'], 'Age': [15, 22, 21, 61, 46] }) df_gender = pd.DataFrame({ 'NAME': ['Jason K.', 'George Jamson', 'Michael Henry', 'Max Jones', 'Tom Reyes,'], 'Gender': ['M', 'M', 'M', 'M', 'M'] }) df_height = pd.DataFrame({ 'NAME': ['Jason Ka', 'George Jameson', 'Michael Henry', 'M. Jones', 'Tom Reyes,'], 'Height(inch)': [76, 65, 68, 60, 80] })
步骤2:定义姓名标准化函数
def standardize_name(name): # 1. 去除标点、首尾空格 cleaned = name.replace('.', '').replace(',', '').strip() # 2. 合并多个连续空格为单个空格 cleaned = ' '.join(cleaned.split()) # 3. 映射已知的姓名变体到标准姓名 variant_map = { 'Jason K': 'Jason Kai', 'Jason Ka': 'Jason Kai', 'George Jamson': 'George Jameson', 'Michael Henry': 'Michael C. Henry', 'M Jones': 'Max Jones' } # 返回标准化结果,无匹配则返回清洗后的姓名 return variant_map.get(cleaned, cleaned)
步骤3:生成匹配键并合并
# 给每个数据集添加标准化姓名列 df_age['standard_name'] = df_age['NAME'].apply(standardize_name) df_gender['standard_name'] = df_gender['NAME'].apply(standardize_name) df_height['standard_name'] = df_height['NAME'].apply(standardize_name) # 基于标准化列合并,保留df_age的原始姓名作为最终展示 merged = pd.merge(df_age, df_gender, on='standard_name', how='left') merged = pd.merge(merged, df_height, on='standard_name', how='left') # 整理最终列 final_df = merged[['NAME_x', 'Age', 'Gender', 'Height(inch)']].rename(columns={'NAME_x': 'NAME'}) print(final_df)
输出结果完全符合你的需求:
NAME Age Gender Height(inch) 0 Jason Kai 15 M 76 1 George Jameson 22 M 65 2 Michael C. Henry 21 M 68 3 Max Jones 61 M 60 4 Tom Reyes 46 M 80
方案二:模糊匹配(适合未知/大量变体)
如果姓名差异不可预见、变体数量多,使用模糊匹配库fuzzywuzzy自动匹配相似度高的姓名,灵活性更强。
步骤1:安装依赖
pip install fuzzywuzzy python-Levenshtein
步骤2:定义模糊匹配函数
from fuzzywuzzy import process # 以第一个数据集的姓名为标准库,匹配相似度≥80的姓名(可调整阈值) def match_standard_name(name, standard_names): best_match, score = process.extractOne(name, standard_names) return best_match if score >= 80 else name # 提取标准姓名列表 standard_names = df_age['NAME'].tolist()
步骤3:生成匹配键并合并
df_gender['standard_name'] = df_gender['NAME'].apply(lambda x: match_standard_name(x, standard_names)) df_height['standard_name'] = df_height['NAME'].apply(lambda x: match_standard_name(x, standard_names)) # 后续合并步骤和方案一一致 merged = pd.merge(df_age, df_gender, on='standard_name', how='left') merged = pd.merge(merged, df_height, on='standard_name', how='left') final_df = merged[['NAME_x', 'Age', 'Gender', 'Height(inch)']].rename(columns={'NAME_x': 'NAME'})
方案选择建议
- 优先用方案一:当你能枚举大部分姓名变体时,匹配准确率100%,运行速度快。
- 用方案二:当姓名变体复杂且无法提前枚举时,牺牲一点性能换灵活性,注意调整相似度阈值(一般80-90比较合适)。
内容的提问来源于stack exchange,提问作者Jason Jiang
相关产品推荐
相关产品推荐

