pandas计算DataFrame两文本列词汇交集占比结果异常排查
问题根因
你的代码计算不符合预期的核心问题是没有做单词拆分:直接把字符串传入set()时,Python会逐字符遍历字符串,生成的是单字符集合,根本不是你需要的按空格分割后的单词集合。
你遇到相同文本计算结果为93.33的问题,是因为其中一列的文本混入了常规空格清洗覆盖不到的不可见特殊字符(比如零宽空格、制表符、换行符、ASCII控制符等),两个视觉上完全一致的字符串,生成的字符集合差了1个特殊元素,最终算出来14/15*100≈93.33,和你遇到的数值完全匹配。
另外注意你当前写的计算逻辑是Jaccard相似度(交集元素数/并集元素数),按这个逻辑blue bowl和green bowl的结果应该是约33.3,和你给出的预期值50不符,如果要完全匹配你列的预期输出,需要调整占比的计算规则。
修复方法
不要直接对原始字符串做集合操作,先把文本按空格拆成单词列表再转集合:
# 保留Jaccard相似度计算逻辑的版本 df['intersection'] = [ len(set(a.split()) & set(b.split())) / len(set(a.split()) | set(b.split())) * 100 if len(set(a.split()) | set(b.split())) > 0 else 0 # 处理空文本避免除零错误 for a, b in zip(df['textcol1'], df['textcol2']) ]
如果要匹配你给出的预期输出(id=1返回50、id=2返回0、id=3返回100),可以把计算规则调整为交集词数除以两列文本的最短词数,代码如下:
# 匹配你给出的样例输出的版本 df['intersection'] = [ len(set(a.split()) & set(b.split())) / min(len(a.split()), len(b.split())) * 100 if min(len(a.split()), len(b.split())) > 0 else 0 for a, b in zip(df['textcol1'], df['textcol2']) ]
如果要彻底避免特殊字符干扰,可以在拆分前加一步清洗,过滤掉所有非字母、非空格的内容:
import re def text_to_wordset(text): # 移除所有非字母、非空格字符,统一转小写后拆分单词 cleaned_text = re.sub(r'[^a-zA-Z\s]', '', str(text).lower()) return set(cleaned_text.split()) df['intersection'] = [ len(text_to_wordset(a) & text_to_wordset(b)) / len(text_to_wordset(a) | text_to_wordset(b)) * 100 if len(text_to_wordset(a) | text_to_wordset(b)) > 0 else 0 for a, b in zip(df['textcol1'], df['textcol2']) ]
内容的提问来源于stack exchange,提问作者Salted
相关产品推荐
相关产品推荐

