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

Julia中高效计算矩阵行两两相关系数的最优方法咨询

问题背景

假设我有一个名为mat的矩阵:

julia> mat = rand(1:10, 5, 3)
5×3 Matrix{Int64}:
 2  4   3
 5  3  10
 5  7   5
 9  5   7
 4  9   6

我需要计算mat每两行之间的相关系数(例如cor(mat[1, :], mat[2, :])),最终得到一个相关矩阵。目前已编写两种实现脚本并完成基准测试,但希望进一步提升计算速度,以处理2000×20甚至10000×100这类大型数据集。

第一种实现方案

这是一种直观方法:先用zeros初始化矩阵,再逐一对每两行计算相关系数并填充。但该方法存在冗余计算(例如cor(mat[1, :], mat[3, :])与cor(mat[3, :], mat[1, :])结果完全相同):

using Statistics

function calc_corr(matrix::Matrix)
    n::Int64 = size(matrix, 1)
    corr_mat = zeros(Float64, n, n)

    for (idx1, idx2)=Iterators.product(1:n, 1:n)
        @inbounds corr_mat[idx1, idx2] = cor(
            view(matrix, idx1, :),
            view(matrix, idx2, :)
        )
    end

    return corr_mat
end
第二种实现方案

先计算相关矩阵的上三角部分,再通过对称矩阵生成完整结果,避免冗余计算:

using LinearAlgebra

function calc_corr2(matrix::Matrix)
    n::Int64 = size(matrix, 1)
    corr_mat = ones(Float64, n, n)

    # 查找上三角索引
    upper_triang_idx = findall(==(1), triu(ones(Int8, n, n), 1))

    for (idx1, idx2)=Tuple.(upper_triang_idx)
        @inbounds corr_mat[idx1, idx2] = cor(
            view(matrix, idx1, :),
            view(matrix, idx2, :)
        )
    end

    corr_mat = Symmetric(corr_mat)
    return corr_mat
end
基准测试

1. 小型矩阵测试

使用上述mat进行测试:

using BenchmarkTools

@benchmark calc_corr($mat)
BenchmarkTools.Trial: 10000 samples with 10 evaluations.
 Range (min … max):  1.950 μs …   6.210 μs  ┊ GC (min … max): 0.00% … 0.00%
 Time  (median):     2.160 μs               ┊ GC (median):    0.00%
 Time  (mean ± σ):   2.178 μs ± 289.600 ns  ┊ GC (mean ± σ):  0.00% ± 0.00%

  ▇▇▂ ▁ ▅█▆▂▁▁▃▆▅▃▁ ▁▁▁▁                                      ▂
  ███████████████████████▆█▇▇█▇▇▆▇▆▇▆▆▄▆▄▄▅▃▁▄▄▄▃▅▃▄▄▄▁▁▁▃▄▁▄ █
  1.95 μs      Histogram: log(frequency) by time      3.62 μs <

 Memory estimate: 256 bytes, allocs estimate: 1.

# ---------------------------------------------------------------------

@benchmark calc_corr2($mat)
BenchmarkTools.Trial: 10000 samples with 10 evaluations.
 Range (min … max):  1.220 μs … 773.080 μs  ┊ GC (min … max): 0.00% … 99.19%
 Time  (median):     1.420 μs               ┊ GC (median):    0.00%
 Time  (mean ± σ):   1.698 μs ±   9.921 μs  ┊ GC (mean ± σ):  8.15% ±  1.40%

  █          
  █▇▃▂▃▄▂▂▄▄▃▂▃▃▂▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ▁
  1.22 μs         Histogram: frequency by time        3.98 μs <

 Memory estimate: 976 bytes, allocs estimate: 7.

验证两种方案结果一致性:

julia> calc_corr(mat) == calc_corr2(mat)
true

2. 大型矩阵测试

test_mat = rand(1:10, 2_000, 20);

@benchmark calc_corr($test_mat)
BenchmarkTools.Trial: 8 samples with 1 evaluation.
 Range (min … max):  632.258 ms … 680.094 ms  ┊ GC (min … max): 0.33% … 1.30%
 Time  (median):     646.215 ms               ┊ GC (median):    0.16%
 Time  (mean ± σ):   650.096 ms ±  16.089 ms  ┊ GC (mean ± σ):  0.49% ± 0.60%

  ▁ ▁           ▁  █       ▁                 ▁                ▁  
  █▁█▁▁▁▁▁▁▁▁▁▁▁█▁▁█▁▁▁▁▁▁▁█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█ ▁
  632 ms           Histogram: frequency by time          680 ms <

 Memory estimate: 30.52 MiB, allocs estimate: 2.

# ---------------------------------------------------------------------

@benchmark calc_corr2($test_mat)
BenchmarkTools.Trial: 14 samples with 1 evaluation.
 Range (min … max):  351.040 ms … 396.431 ms  ┊ GC (min … max): 2.58% … 1.81%
 Time  (median):     357.403 ms               ┊ GC (median):    2.86%
 Time  (mean ± σ):   360.863 ms ±  11.661 ms  ┊ GC (mean ± σ):  2.75% ± 0.80%

    █           
  ▇▁█▇▁▇▇▁▁▁▇▁▁▁▇▇▁▇▁▁▇▁▇▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▇ ▁
  351 ms           Histogram: frequency by time          396 ms <

 Memory estimate: 99.63 MiB, allocs estimate: 14.

当前内存不是主要关注点,但面对10000×100这类超大矩阵时,现有方案速度仍不够理想,寻求能进一步提升计算速度的优化建议。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:50:38