如何实现技能词列表与DataFrame自由文本列的匹配分类?
技能词匹配解决方案
原代码存在的问题
- 用
y in repo判断匹配时,会误把子串当成匹配(比如技能词是python,文本里的pyth会被错误识别为匹配) - 通过
split()拆分文本,无法匹配多词技能短语(比如machine learning会被拆成两个独立单词,无法完整匹配) - 缺少未匹配文本的提取逻辑
修正后的实现方案
1. 基础数据预处理
先读取并清洗数据,统一转为小写避免大小写干扰:
import pandas as pd import re # 读取技能表与职位描述表,清理无效列 skills = pd.read_excel(r"C:\Users\m1056565\Downloads\final_skill.xlsx").drop(['Unnamed: 0'], axis=1) jd = pd.read_excel(r"C:\Users\m1056565\Downloads\job_descriptiopn.xlsx", nrows=100).drop(['Unnamed: 0'], axis=1) # 将技能词转为小写,避免大小写匹配问题 skills['skills_lower'] = skills['skills'].astype(str).str.lower() skill_list = skills['skills_lower'].tolist()
2. 完全匹配(完整单词/短语)
匹配文本中完整出现的技能词(包括多词短语),避免子串误匹配:
# 对技能词转义,避免正则特殊字符干扰 escaped_skills = [re.escape(skill) for skill in skill_list] # 构建正则模式,用单词边界\b确保匹配完整词/短语 pattern_full = re.compile(r'\b(' + '|'.join(escaped_skills) + r')\b', flags=re.IGNORECASE) # 提取完全匹配的技能词(去重) def get_full_matches(text): text_lower = str(text).lower() matches = pattern_full.findall(text_lower) return ' '.join(set(matches)) # 提取未匹配的文本内容 def get_unmatched_text(text): text_lower = str(text).lower() # 替换掉所有匹配到的技能词,清理多余空格 unmatched = pattern_full.sub('', text_lower) return ' '.join(unmatched.split()) # 新增匹配结果列 jd['完全匹配技能'] = jd['JobDescription'].apply(get_full_matches) jd['未匹配文本'] = jd['JobDescription'].apply(get_unmatched_text)
3. 部分匹配(技能词作为子串)
如果需要匹配文本中包含技能词的内容(比如技能词sql可匹配mysql):
escaped_skills = [re.escape(skill) for skill in skill_list] # 去掉单词边界,直接匹配子串 pattern_partial = re.compile(r'(' + '|'.join(escaped_skills) + r')', flags=re.IGNORECASE) # 提取部分匹配的技能词(去重) def get_partial_matches(text): text_lower = str(text).lower() matches = pattern_partial.findall(text_lower) return ' '.join(set(matches)) # 提取未匹配文本 def get_unmatched_partial(text): text_lower = str(text).lower() unmatched = pattern_partial.sub('', text_lower) return ' '.join(unmatched.split()) # 新增部分匹配结果列 jd['部分匹配技能'] = jd['JobDescription'].apply(get_partial_matches) jd['未匹配文本(含部分匹配)'] = jd['JobDescription'].apply(get_unmatched_partial)
4. 合并完全+部分匹配结果
如果需要将两种匹配结果合并:
def get_all_matches(text): text_lower = str(text).lower() full_matches = pattern_full.findall(text_lower) partial_matches = pattern_partial.findall(text_lower) # 合并后去重 all_matches = list(set(full_matches + partial_matches)) return ' '.join(all_matches) jd['所有匹配技能'] = jd['JobDescription'].apply(get_all_matches)
内容的提问来源于stack exchange,提问作者Abhishek Prasar
相关产品推荐
相关产品推荐

