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

计算DataFrame列间Jaccard相似度时代码出错求助

问题分析与代码修正

两段代码的核心错误

第一段代码的问题

  • 遍历df.items()时未正确获取列对,反而使用了未定义的变量i和j,导致计算值固定,最终所有矩阵位置被覆盖为同一结果。
  • 每次循环都重新创建pd.DataFrame,之前的计算结果被完全覆盖,最后仅保留最后一次计算的单一值。

第二段代码的问题

  • 外层循环range(len(df))遍历的是行索引而非列;内层循环虽遍历列索引,但直接把整数索引i和j传给相似度函数,而非对应的列数据。
  • 传入整数时,np.logical_and(i,j)只要两个整数不为0就返回True,intersection.sum()和union.sum()均为1,因此相似度始终为1。

修正后的代码实现

先重写纯Python版的Jaccard相似度函数(不依赖numpy),再通过列遍历生成相似度矩阵:

def jaccard_binary(x, y):
    """计算两个二进制向量的Jaccard相似度"""
    if len(x) != len(y):
        raise ValueError("两个向量长度必须一致")
    intersection = sum(a & b for a, b in zip(x, y))
    union = sum(a | b for a, b in zip(x, y))
    # 处理并集为0的特殊情况
    return intersection / union if union != 0 else 0.0

# 获取所有列名
columns = df.columns.tolist()
n_cols = len(columns)
# 初始化空的相似度矩阵
jac_sim = [[0.0 for _ in range(n_cols)] for _ in range(n_cols)]

# 双重循环遍历所有列对
for i in range(n_cols):
    col_i = df[columns[i]].tolist()
    for j in range(n_cols):
        col_j = df[columns[j]].tolist()
        jac_sim[i][j] = jaccard_binary(col_i, col_j)

# 转换为DataFrame格式
jac_sim_df = pd.DataFrame(jac_sim, index=columns, columns=columns)
print(jac_sim_df)

关键说明

  • 提前初始化与列数匹配的二维列表,避免循环中覆盖之前的计算结果。
  • 遍历列索引时,取出对应列的实际数据传入函数,确保计算的是列向量间的相似度。
  • 加入长度校验和除零保护,提升代码的鲁棒性,适配后续其他列遍历计算的扩展需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 00:12:55