如何用SequenceMatcher对比DataFrame的name列与多match列并获取最优匹配?
解决方案
直接用pandas.DataFrame.apply遍历每行,结合difflib.SequenceMatcher计算匹配度,同时过滤空值,具体步骤如下:
- 导入依赖库
import pandas as pd from difflib import SequenceMatcher
- 定义处理单行的函数
这个函数会接收每行数据,提取name和match1-match4列,过滤掉空值后逐一计算匹配度,最后返回匹配度最高的结果(如果所有match列都为空,返回NaN):
def get_best_match(row): name = row['name'] # 获取所有match列的值,过滤NaN match_candidates = [row[col] for col in ['match1', 'match2', 'match3', 'match4'] if pd.notna(row[col])] if not match_candidates: return pd.NA # 无有效匹配项时返回空 # 计算每个候选的匹配度,存储(匹配度, 候选值)元组 match_ratios = [] for candidate in match_candidates: ratio = SequenceMatcher(None, name, candidate).ratio() match_ratios.append((ratio, candidate)) # 按匹配度降序排序,取第一个的候选值 match_ratios.sort(reverse=True, key=lambda x: x[0]) return match_ratios[0][1]
- 应用函数到DataFrame
假设你的DataFrame名为df,直接用apply函数处理每行,新增best_match列:
df['best_match'] = df.apply(get_best_match, axis=1)
测试示例
比如创建一个测试DataFrame:
data = { 'id': [1, 2, 3], 'name': ['Alice Smith', 'Bob Johnson', 'Charlie Brown'], 'match1': ['Alice S.', pd.NA, 'Charlie B.'], 'match2': ['Alic Smith', 'Bob J.', pd.NA], 'match3': [pd.NA, pd.NA, 'Charlie Brown'], 'match4': ['Alex Smith', 'Robert Johnson', pd.NA] } df = pd.DataFrame(data)
运行上述代码后,df['best_match']会得到:
- 第一行:
Alice S.(匹配度最高) - 第二行:
Bob J. - 第三行:
Charlie Brown(完全匹配)
关键说明
- 不需要重塑数据格式,直接行级遍历处理,避开了NaN的重塑问题
- 函数里先过滤空值,避免计算NaN和字符串的匹配度报错
- 如果需要返回匹配度数值而不是匹配项,只需要把
return match_ratios[0][1]改成return match_ratios[0][0]即可
内容的提问来源于stack exchange,提问作者Sammyg
相关产品推荐
相关产品推荐

