在Pandas DataFrame中实现Col1与Col2的匹配查询及匹配度标注
Pandas字符串匹配与分类标注问题
原始数据
创建DataFrame的代码:
import pandas as pd data = {'Col1': ['Bad Homburg', 'Bischofferode', 'Essen', 'Grabfeld OT Rentwertshausen','Großkrotzenburg','Jesewitz/Weg','Kirchen (Sieg)','Laudenbach a. M.','Nachrodt-Wiblingwerde','Rehburg-Loccum','Dingen','Burg (Dithmarschen)'], 'Col2': ['Rehburg-Loccum','Grabfeld','Laudenbach','Kirchen','Jesewitz','Großkrotzenburg','Nachrodt-','Essen/Stadt','Bischofferode','Bad Homburg','Münster','Burg']} df = pd.DataFrame(data)
原始表格内容:
| Col1 | Col2 |
|---|---|
| Bad Homburg | Rehburg-Loccum |
| Bischofferode | Grabfeld |
| Essen | Laudenbach |
| Grabfeld OT Rentwertshausen | Kirchen |
| Großkrotzenburg | Jesewitz |
| Jesewitz/Weg | Großkrotzenburg |
| Kirchen (Sieg) | Nachrodt- |
| Laudenbach a. M. | Essen/Stadt |
| Nachrodt-Wiblingwerde | Bischofferode |
| Rehburg-Loccum | Bad Homburg |
| Dingen | Münster |
| Burg (Dithmarschen) | Burg |
需求
为每一行的Col1值,在整个Col2列的所有值中查找匹配项,生成两列:
Lookup_value:匹配到的Col2值(无匹配则为空)Comment:标注匹配类型:- 100% Matched:Col1值与某个Col2值完全相等
- Best Possible Match:Col1与Col2值存在部分匹配(如子串、前缀/后缀重合)
- No Match:无任何匹配
预期结果:
| Col1 | Col2 | Lookup_value | Comment |
|---|---|---|---|
| Bad Homburg | Rehburg-Loccum | Bad Homburg | 100% Matched |
| Bischofferode | Grabfeld | Bischofferode | 100% Matched |
| Essen | Laudenbach | Essen/Stadt | Best Possible Match |
| Grabfeld OT Rentwertshausen | Kirchen | Grabfeld | Best Possible Match |
| Großkrotzenburg | Jesewitz | Großkrotzenburg | 100% Matched |
| Jesewitz/Weg | Großkrotzenburg | Jesewitz | Best Possible Match |
| Kirchen (Sieg) | Nachrodt- | Kirchen | Best Possible Match |
| Laudenbach a. M. | Essen/Stadt | Laudenbach | Best Possible Match |
| Nachrodt-Wiblingwerde | Bischofferode | Nachrodt- | Best Possible Match |
| Rehburg-Loccum | Bad Homburg | Rehburg-Loccum | 100% Matched |
| Dingen | Münster | No Match | |
| Burg (Dithmarschen) | Burg | Burg | Best Possible Match |
错误代码分析
你之前的代码存在两个核心问题:
- 仅在当前行的Col2值中查找,而非整个Col2列的所有值
- 匹配判断逻辑颠倒(
col1_value in col2_value无法覆盖Col2值是Col1子串的情况)
错误代码:
def lookup_value_and_comment(row): col1_value = row['Col1'] col2_value = row['Col2'] if col1_value in col2_value: if col1_value == col2_value: return pd.Series([col1_value, '100% Matched'], index=['Lookup_value', 'Comment']) else: return pd.Series([col2_value, 'Best Possible Match'], index=['Lookup_value', 'Comment']) else: return pd.Series(['', 'No Match'], index=['Lookup_value', 'Comment']) df[['Lookup_value', 'Comment']] = df.apply(lookup_value_and_comment, axis=1) print(df)
正确解决方案
思路
- 预存Col2的所有值作为候选匹配集合
- 对每个Col1值,优先检查是否存在完全匹配的Col2值
- 若无完全匹配,查找是否存在部分匹配(子串包含、前缀/后缀匹配),取第一个符合条件的匹配项
- 若无任何匹配,标记为无匹配
完整代码
import pandas as pd data = {'Col1': ['Bad Homburg', 'Bischofferode', 'Essen', 'Grabfeld OT Rentwertshausen','Großkrotzenburg','Jesewitz/Weg','Kirchen (Sieg)','Laudenbach a. M.','Nachrodt-Wiblingwerde','Rehburg-Loccum','Dingen','Burg (Dithmarschen)'], 'Col2': ['Rehburg-Loccum','Grabfeld','Laudenbach','Kirchen','Jesewitz','Großkrotzenburg','Nachrodt-','Essen/Stadt','Bischofferode','Bad Homburg','Münster','Burg']} df = pd.DataFrame(data) # 提取Col2的所有候选值 col2_candidates = df['Col2'].tolist() def find_match(col1_val): # 先检查完全匹配 for val in col2_candidates: if val == col1_val: return (val, '100% Matched') # 检查部分匹配:Col2值是Col1的子串,或者Col1是Col2值的子串,或者前缀匹配 for val in col2_candidates: if val in col1_val or col1_val in val or val.strip('-') in col1_val.split()[0]: return (val, 'Best Possible Match') # 无匹配 return ('', 'No Match') # 应用函数生成新列 df[['Lookup_value', 'Comment']] = df['Col1'].apply(lambda x: pd.Series(find_match(x))) print(df)
结果验证
运行上述代码后,生成的DataFrame与预期结果完全一致。
内容的提问来源于stack exchange,提问作者s_max
相关产品推荐
相关产品推荐

