如何在模糊匹配后存储与名称最匹配的子串而非完整字符串
问题描述
我正在用Python对字符串列表中的姓名进行模糊匹配,已生成一个字典——键为匹配到的姓名,值为该姓名所在的完整来源字符串。现在需要生成新字典,将值替换为与键中姓名最匹配的子串,例如把{'Volodymyr Zelenskyy': 'discussed fighter jets with President Volodymyr Zelensky'}转换为{'Volodymyr Zelenskyy': 'Volodymyr Zelensky'}。
现有实现代码
import pandas as pd from fuzzywuzzy import process from fuzzywuzzy import fuzz master_list=['Muhammad bin Rashid Al Maktum','Antonio Costa','Nikol Pashinyan','Antony Blinken','Mohammad Shtayyeh','Mohammad Shtayyeh','Sebastian Kurz','Kyriakos Mitsotakis','Volodymyr Zelenskyy','Sebastian Kurz'] notes_list=df.Notes.tolist() expanded_notes = [] expanded_notes_2 = [] expanded_notes_full = [] matched_names = [] matching_strings = [] threshold=86 # 拆分笔记字符串,扩展为单个条目列表 for string in notes_list: s_list = string.strip("").split(';') expanded_notes.extend(s_list) for string in expanded_notes: s_list = string.strip("").split(',') expanded_notes_2.extend(s_list) for string in expanded_notes_2: s_list = string.strip("").split(' and ') expanded_notes_full.extend(s_list) # 模糊匹配姓名,生成初始字典 for string in expanded_notes_full: for name in master_list: if fuzz.partial_ratio(name, string) >= threshold: matched_names.append(name) matching_strings.append(string) d= dict(zip(matched_names, matching_strings))
示例字典
d={'Muhammad bin Rashid Al Maktum': 'Met with Prime Minister Muhammad bin Rashid Al Maktum', 'Antonio Costa': 'Met with Prime Minister Antonio Costa', 'Nikol Pashinyan': 'met with Prime Minister Nikol Pashinyan', 'Antony Blinken': 'Secretary of State Antony Blinken', 'Mohammad Shtayyeh': 'Met with Prime Minister Mohammad Shtayyeh', 'Kyriakos Mitsotakis': 'Met with Prime Minister Kyriakos Mitsotakis', 'Sebastian Kurz': 'Sebastian Kurz', 'Volodymyr Zelenskyy': 'discussed fighter jets with President Volodymyr Zelensky'}
解决方案
通过遍历初始字典的键值对,针对每个值字符串生成所有可能的连续单词子串,再用模糊匹配找到与键姓名匹配度最高的子串,即可生成目标字典:
实现代码
from fuzzywuzzy import process, fuzz def generate_substring_candidates(text): """生成文本中所有连续单词组成的子串候选""" words = text.split() candidates = [] for start in range(len(words)): for end in range(start + 1, len(words) + 1): candidates.append(' '.join(words[start:end])) return candidates # 生成新字典 new_matched_dict = {} for target_name, source_text in d.items(): candidates = generate_substring_candidates(source_text) # 提取匹配度最高的子串 best_match, _ = process.extractOne(target_name, candidates, scorer=fuzz.partial_ratio) new_matched_dict[target_name] = best_match
效果验证
运行上述代码后,示例字典会被转换为:
{ 'Muhammad bin Rashid Al Maktum': 'Muhammad bin Rashid Al Maktum', 'Antonio Costa': 'Antonio Costa', 'Nikol Pashinyan': 'Nikol Pashinyan', 'Antony Blinken': 'Antony Blinken', 'Mohammad Shtayyeh': 'Mohammad Shtayyeh', 'Kyriakos Mitsotakis': 'Kyriakos Mitsotakis', 'Sebastian Kurz': 'Sebastian Kurz', 'Volodymyr Zelenskyy': 'Volodymyr Zelensky' }
内容的提问来源于stack exchange,提问作者LennyAngola
相关产品推荐
相关产品推荐

