Pandas字符串匹配优化:为文本匹配最优Code的实现方案
解决思路与实现方法
核心逻辑:优先匹配更具体的关键词
问题本质是短关键词会覆盖长组合关键词,所以关键是让更具体(长度更长、包含更多词汇)的关键词先被匹配,一旦匹配成功就停止检查更短的关键词。
步骤1:预处理codes数据
先把codes中的关键词拆分为单独条目,再按关键词长度降序排序,确保像chicken burger这类组合关键词排在burger前面,避免被短关键词抢先匹配。
示例代码:
import pandas as pd # 模拟你的原始数据 codes = pd.DataFrame({ "code": ["bg", "cbg"], "keywords": [["burger", "burgers"], ["chicken burger", "chicken burgers"]] }) # 展开每个code的关键词为单独行 codes_expanded = codes.explode("keywords").reset_index(drop=True) # 按关键词长度降序排序,长关键词优先匹配 codes_expanded["kw_length"] = codes_expanded["keywords"].str.len() codes_expanded = codes_expanded.sort_values("kw_length", ascending=False).reset_index(drop=True)
步骤2:自定义匹配函数
针对每条文本,遍历排序后的关键词,找到第一个匹配的code。同时处理大小写不敏感问题,进阶版还能解决复数、时态等词汇变体的匹配。
基础版(大小写不敏感)
def match_code(text): text_lower = text.lower() for _, row in codes_expanded.iterrows(): if row["keywords"].lower() in text_lower: return row["code"] return None # 无匹配时返回None # 模拟phrases数据并应用匹配函数 phrases = pd.DataFrame({ "text": ["burgers near me", "chicken burgers around NYC", "beef burger shop"] }) phrases["matched_code"] = phrases["text"].apply(match_code)
运行后,chicken burgers around NYC会匹配cbg,burgers near me匹配bg,符合预期。
进阶版(处理词汇变体)
用词干提取统一词汇形态(比如把burgers转为burger),提升匹配精度:
from nltk.stem import SnowballStemmer stemmer = SnowballStemmer("english") def stem_text(text): return " ".join([stemmer.stem(word) for word in text.lower().split()]) # 预处理关键词的词干 codes_expanded["kw_stem"] = codes_expanded["keywords"].apply(stem_text) def match_code_stem(text): text_stem = stem_text(text) for _, row in codes_expanded.iterrows(): if row["kw_stem"] in text_stem: return row["code"] return None phrases["matched_code"] = phrases["text"].apply(match_code_stem)
步骤3:大数据量优化(避免循环)
如果数据量很大,循环遍历效率低,可以用矢量化操作加速:
import numpy as np # 生成匹配矩阵:每行对应一个关键词,每列对应一条text,值为是否匹配 match_matrix = phrases["text"].str.lower().apply( lambda x: codes_expanded["keywords"].str.lower().str.contains(x) ).T # 找到每条text第一个匹配的关键词索引 first_match_idx = match_matrix.idxmax(axis=0) # 映射到对应的code phrases["matched_code"] = codes_expanded.loc[first_match_idx, "code"].values # 处理无匹配的情况 phrases["matched_code"] = np.where(match_matrix.any(axis=0), phrases["matched_code"], None)
内容的提问来源于stack exchange,提问作者Rahul Srikhakolanu
相关产品推荐
相关产品推荐

