You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python按阈值筛选Jaccard相似度行的问题修正

解决Jaccard相似度筛选问题(排除自身匹配、过滤无结果行)

问题分析

你的代码存在三个核心问题:

  1. 未排除自身匹配:遍历所有行时包含了当前行与自身的对比,当阈值设为>0.95时,自身相似度为1,会被纳入结果。
  2. 保留了无符合条件的行:无论当前行是否有匹配的其他行,都会被添加到输出DataFrame,导致出现多余的空结果行。
  3. 字符串分割未处理空格:split(',')得到的元素带空格(如['dog', ' cat']),会导致集合交集计算错误,影响Jaccard值准确性。

修正后的代码

import pandas as pd

data = {
    'letters': ['a', 'b', 'c', 'd'],
    'animals': ['dog, cat, fish', 'cat, fish', 'dog, bird, fish', 'dog']
}

df = pd.DataFrame(data)

def jaccard(list1, list2):
    # 去除每个元素的空格,避免因空格导致集合匹配错误
    set1 = set(item.strip() for item in list1)
    set2 = set(item.strip() for item in list2)
    intersection = len(set1 & set2)
    union = len(set1 | set2)
    # 处理union为0的极端情况(当前数据不会出现,增加健壮性)
    return float(intersection) / union if union != 0 else 0.0

out_data = []
threshold_low = 0.3
threshold_high = 0.4

for ind1, r1 in df.iterrows():
    matched_ids = []
    # 遍历其他行,跳过自身
    for ind2, r2 in df.iterrows():
        if ind1 == ind2:
            continue
        # 分割动物列表并计算相似度
        sim = jaccard(r1['animals'].split(','), r2['animals'].split(','))
        if threshold_low < sim <= threshold_high:
            matched_ids.append(r2['letters'])
    # 仅当有匹配结果时才添加到输出
    if matched_ids:
        out_data.append({
            'letters': r1['letters'],
            'animals': r1['animals'],
            'sub-animal-letters': ','.join(matched_ids)
        })

# 转换为DataFrame并输出
out_df = pd.DataFrame(out_data)
print(out_df)

代码说明

  • 处理空格问题:在Jaccard函数中用item.strip()去除每个动物名称的前后空格,确保集合对比准确。
  • 排除自身匹配:添加if ind1 == ind2: continue跳过当前行与自身的对比。
  • 过滤无结果行:只有当matched_ids不为空时,才将该行加入输出列表,避免多余空行。
  • 优化Jaccard计算:用集合运算符&和|替代intersection和union方法,代码更简洁。

运行结果(阈值0.3~0.4)

lettersanimalssub-animal-letters
adog, cat, fishd
cdog, bird, fishd

当阈值设为>0.95时,不会出现自身匹配的结果,因为已经跳过了自身对比逻辑。

内容的提问来源于stack exchange,提问作者abcabc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 11:37:48