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
相关产品推荐
相关产品推荐

