基于Python NLP的两列相似句子匹配及价格对齐输出方案
两列商品文本相似度匹配实现方案
依赖安装
需要用到pandas处理表格数据,fuzzywuzzy做短文本模糊匹配,执行以下命令安装依赖:
pip install pandas fuzzywuzzy python-Levenshtein
如果遇到Levenshtein安装失败,可以跳过,fuzzywuzzy会自动降级用纯Python实现匹配,只是速度稍慢。
实现逻辑
针对你给出的商品名匹配场景,核心逻辑如下:
- 先做数据预处理:把原始表格的空值统一标记,提取所有非空的string2作为候选匹配池
- 相似度计算用
token_sort_ratio算法:会自动忽略大小写、词序差异,先把文本分词、排序后再计算编辑距离,非常适合商品名这种词序不固定、存在缩写/大小写差异的场景 - 设置相似度阈值(默认推荐80,可根据实际匹配效果调整),得分高于阈值则判定为匹配,每个string2只会被匹配一次,避免重复占用
- 最后按要求格式化输出:空值统一标NA,无匹配的string2列标Not Found
完整实现代码
import pandas as pd from fuzzywuzzy import fuzz from fuzzywuzzy import process # 1. 加载数据,这里可以替换成你自己的文件读取代码,比如pd.read_excel("原始数据.xlsx") # 以下为模拟样本数据的示例 data = { "A header": ["PIKSTERS"]*7 + ["NIVEA"]*4, "string1": [ "PIKSTERS SUPAGRIPS 20PK", "PIKSTERS SUPAGRIPS 50PK", "PIKSTERS SIZE 1 PRPL 40PK", "PIKSTERS SIZE 5 BL 40PK", "PIKSTERS SIZE 6 GRN 40PK", "PIKSTERS INTERDENTAL BRUSH SIZE 00 (40 PACK)", "PIKSTERS HYDRO PICK", "NIVEA D/ES 3IN1 Cleanser WIPES MINI PK", "NIVEA VISAGE Cleanser WIPES REFR FACE25", "NIVEA D/ES EYE MUP REM 125ML", "NIVEA D/ES SPF30+ SENS DAY Cream 50ML" ], "Price": [25,55,35,65,15,75,85,95,105,115, None], "Another header": ["NIVEA","Nivea","Nivea","Piksters","Piksters","Piksters","Piksters"] + [None]*4, "string2": [ "NIVEA D/ES EYE MUP REM 125ML", "Nivea Q10 Power Protecting Day Cream SPF3050ml", "Nivea Lip Care Hydro Care 4.8g", "Piksters Bamboo Inter Brush 8 Pack Size 5 Online Only", "Piksters Bamboo Inter Brush 8 Pack Size 00 Online Only", "Piksters Supa Grips 50 Pack", "Piksters Supa Grips 20 Pack", None, None, None, None ] } df = pd.DataFrame(data) # 2. 提取非空的string2候选池,保存对应的品牌列 candidates = df[df["string2"].notna()][["Another header", "string2"]].drop_duplicates().values.tolist() used_candidates = set() # 标记已匹配的条目,避免重复匹配 # 3. 匹配函数 def match_item(s1): if pd.isna(s1): return ("NA", "Not Found") # 过滤已使用的候选 available = [c for c in candidates if c[1] not in used_candidates] if not available: return ("NA", "Not Found") # 计算最高相似度的匹配项 str2_list = [c[1] for c in available] best_match, score = process.extractOne(s1, str2_list, scorer=fuzz.token_sort_ratio) # 阈值可根据实际效果调整 if score >= 80: used_candidates.add(best_match) matched_info = [c for c in available if c[1] == best_match][0] return (matched_info[0], matched_info[1]) else: return ("NA", "Not Found") # 4. 执行匹配 df[["Another header", "string2"]] = df["string1"].apply(lambda x: pd.Series(match_item(x))) # 5. 空值格式化 df["Price"] = df["Price"].fillna("NA") # 6. 输出结果,可替换为df.to_excel("匹配结果.xlsx", index=False)导出文件 print(df)
大数据量优化方案
如果你的数据量超过1万条,模糊匹配速度会比较慢,可以替换成语义向量检索方案:用sentence-transformers把所有string2转成语义向量,再用FAISS构建索引,查询时直接检索最相似的向量,匹配速度会提升几十倍。
内容的提问来源于stack exchange,提问作者Murphy
相关产品推荐
相关产品推荐

