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

在Julia中基于(obj,obj,距离/相似度)三元组生成成对距离矩阵

优化方案

你原来的实现效率低的核心问题是嵌套循环中每次都对整个r矩阵做布尔索引查找,时间复杂度为O(N²*M)(N为唯一对象数,M为三元组行数),数据量稍大就会有明显的性能瓶颈。可以通过一次遍历+索引映射的方式把时间复杂度降到O(M+N²),性能能提升几个数量级。

实现1:单循环索引赋值

using NamedArrays

function DistanceMatrixFromTriColumn(r::AbstractArray)
    # 生成名称到整数索引的映射,避免重复查找
    names = unique(vcat(r[:, 1], r[:, 2]))
    name2idx = Dict(name => i for (i, name) in enumerate(names))
    n = length(names)
    dist = NamedArray(zeros(n, n), (names, names))

    # 仅遍历一次三元组完成赋值,无需重复扫描全矩阵
    for i in 1:size(r, 1)
        row_idx = name2idx[r[i, 1]]
        col_idx = name2idx[r[i, 2]]
        dist[row_idx, col_idx] = r[i, 3]
    end
    return dist
end

实现2:向量化索引赋值(更接近R语言的操作风格)

如果你习惯R语言的向量化操作风格,可以用笛卡尔索引直接批量赋值,完全避免显式循环:

using NamedArrays

function DistanceMatrixFromTriColumn(r::AbstractArray)
    names = unique(vcat(r[:, 1], r[:, 2]))
    name2idx = Dict(name => i for (i, name) in enumerate(names))
    n = length(names)
    dist_mat = zeros(n, n)
    
    # 批量生成坐标,一次性赋值
    rows = [name2idx[v] for v in r[:, 1]]
    cols = [name2idx[v] for v in r[:, 2]]
    dist_mat[CartesianIndex.(rows, cols)] = r[:, 3]
    
    return NamedArray(dist_mat, (names, names))
end

两种实现的输出和你原来的代码完全一致,在数据量较大时(比如10万级以上三元组),性能提升可达数十到上百倍。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 00:15:00