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

pandas中空列表两两计算杰卡德相似度触发ZeroDivisionError解决方法

问题根因

计算杰卡德相似度时触发ZeroDivisionError: float division by zero的直接原因是:当参与比对的两个列表均为空列表时,二者转成集合后的并集元素数量为0,原函数直接执行「交集大小/并集大小」的除法运算,触发除零异常。

修复方法

在杰卡德相似度计算函数中增加边界判断即可,按照集合相似度的通用计算约定,两个空集合完全相等,相似度取值为1.0,只需要在做除法前拦截并集长度为0的场景即可。

  • 双空列表场景:直接返回约定的相似度值,不执行除法运算
  • 单空列表+非空列表场景:并集长度等于非空列表的去重元素数,交集长度为0,原有逻辑计算返回0.0,不会触发异常
  • 双非空列表场景:完全沿用原有计算逻辑,不影响正常结果

修复后可运行代码

import itertools
import pandas as pd

# 测试DataFrame构造
df = pd.DataFrame({
    "wordings": [[], [], [], ["模型", "算法"], ["算法", "数据"], ["模型"]],
    "users": ["用户1", "用户2", "用户3", "用户4", "用户5", "用户6"],
    "phase": ["阶段A", "阶段B", "阶段A", "阶段B", "阶段A", "阶段B"]
})

def jaccard_similarity(list_a: list, list_b: list) -> float:
    set_a = set(list_a)
    set_b = set(list_b)
    inter_len = len(set_a & set_b)
    union_len = len(set_a | set_b)
    # 拦截双空列表的边界场景,避免除零
    if union_len == 0:
        return 1.0
    return inter_len / union_len

# 两两比对计算
sim_result = []
record_tuples = list(zip(df["wordings"], df["users"], df["phase"]))
for (words1, user1, phase1), (words2, user2, phase2) in itertools.combinations(record_tuples, 2):
    score = jaccard_similarity(words1, words2)
    sim_result.append({
        "对比用户A": user1,
        "A所属阶段": phase1,
        "对比用户B": user2,
        "B所属阶段": phase2,
        "杰卡德相似度": round(score, 4)
    })

# 输出结果
result_df = pd.DataFrame(sim_result)
print(result_df)
可选调整说明

如果业务规则对双空列表的相似度有特殊定义,比如认为两条无有效词汇的记录相似度为0、或者标记为空值,只需要修改union_len == 0分支下的返回值即可,核心逻辑是提前拦截并集长度为0的场景,从根源上避免除零运算。

注意:计算杰卡德相似度前一定要先把列表转成集合去重,否则重复元素会导致交集、并集长度计算错误,影响最终结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 23:18:33