Pandas按优先级实现字符串前缀模糊匹配类VLOOKUP表连接
pandas实现变长前缀匹配的类VLOOKUP方案
你的长前缀优先排序思路是正确的,直接基于排序后的前缀列表做逐行前缀命中即可,实现步骤如下:
- 预处理参考映射表
先对存储前缀映射的df1按前缀长度降序排序,保证长前缀优先参与匹配,避免短前缀提前抢占匹配结果,排序后将前缀和对应全称转为列表提升遍历效率:
import pandas as pd df1 = pd.DataFrame({'Abb': ['G', 'GRE', 'Gou', 'B'], 'FullName': ['Gouna', 'GreenLand', 'Gouna', 'Bahr']}) df2 = pd.DataFrame({'OrderNo': ['INV20561', 'INV20562', 'INV20563', 'INV20564'], 'AreaName': ['GRE65335', 'Gou6D654', 'Gddd654', 'B65465']}) # 按前缀长度降序排序,重置索引避免顺序异常 df1_sorted = df1.sort_values(by="Abb", key=lambda x: x.str.len(), ascending=False, ignore_index=True) # 提前构建前缀-全称映射列表 prefix_mapping = list(zip(df1_sorted['Abb'], df1_sorted['FullName']))
- 编写前缀匹配函数
对每个待匹配的区域字符串,按排序后的前缀顺序遍历,返回第一个命中前缀对应的全称,无匹配时可自定义返回值:
def get_full_name(area_str): for abb, full_name in prefix_mapping: # 前缀命中判断,如需不区分大小写可改为 area_str.upper().startswith(abb.upper()) if area_str.startswith(abb): return full_name return None # 无匹配时默认返回空,可按需修改为"未匹配"等自定义值
- 生成匹配结果列
直接对df2的AreaName列应用匹配函数,即可得到最终结果:
df2['FullName'] = df2['AreaName'].apply(get_full_name) print(df2)
运行后输出与预期完全一致:
OrderNo AreaName FullName 0 INV20561 GRE65335 GreenLand 1 INV20562 Gou6D654 Gouna 2 INV20563 Gddd654 Gouna 3 INV20564 B65465 Bahr
可选优化说明
- 数据量超过10万行时,可构建前缀树(Trie)结构替换线性遍历,进一步提升匹配性能,常规业务数据量下上述实现性能足够。
- 若存在相同长度的前缀可能命中同一字符串,可在排序时增加第二排序规则,按业务优先级指定同长度前缀的匹配顺序。
- 示例中df1初始打印的B对应值为Bahrain、后续期望结果为Bahr属于笔误,实际使用时替换为真实映射值即可。
内容的提问来源于stack exchange,提问作者Nagib
相关产品推荐
相关产品推荐

