怎么遍历 SparseMatrixCSC 中的非零元素呢?

现在只会双重循环遍历,速度太慢了,没找到相关的 API。

50279×50279 SparseArrays.SparseMatrixCSC{Float64,Int32} with 83679 stored entries:
  [21812,     1]  =  0.0106611
  [3398 ,     2]  =  0.00447397
  [29867,     2]  =  0.0626186
  [39189,     2]  =  0.0605122
  [19779,     3]  =  0.0410516
  [5345 ,     4]  =  0.0365283
  [5904 ,     4]  =  0.0428285
  [13946,     5]  =  0.403453
  [9785 ,     6]  =  0.121049
  [21285,     6]  =  0.111286
  [9397 ,     7]  =  0.206972
  [23159,     7]  =  0.0733745
using SparseArrays

a = sprandn(40,40,0.01);


@time for (x,y,v) in zip(findnz(a)...)
  println(x,' ',y,' ',v)
end

function print_nz(A)
    for col in 1:size(A, 2)
        for r in nzrange(A, col)
            println(rowvals(A)[r], ' ', col, ' ',  nonzeros(A)[r])
        end
    end
end

@time print_nz(a)

对于真的稀疏的稀疏矩阵,还是上述的方法一快,即,链接中上面那个方法。

我测的是方法2快

a = sprandn(4000, 400, 0.01)
using BenchmarkTools
function printnz1(A)
    for (x, y, v) in zip(findnz(A)...)
        # println(x, ' ', y, ' ', v) 
        res = x + y + v
    end
end
@btime printnz1(a)

function print_nz(A)
    for col in 1:size(A, 2)
        for r in nzrange(A, col)
            # println(rowvals(A)[r], ' ', col, ' ',  nonzeros(A)[r])
            res = rowvals(A)[r] + col + nonzeros(A)[r]
        end
    end
end

@btime print_nz(a)

24.556 μs (6 allocations: 372.42 KiB)
9.576 μs (0 allocations: 0 bytes)

using SparseArrays
using BenchmarkTools
a = sprandn(500, 500, 0.001)

function printnz1(A)
    xx = [];yy=[];vv=[];
    for (x, y, v) in zip(findnz(A)...)
        # println(x, ' ', y, ' ', v);
        # res = x + y + v
        push!(xx,x);
        push!(yy,y);
        push!(vv,v);
    end
end


function print_nz(A)
    xx = [];yy=[];vv=[];
    for col in 1:size(A, 2)
        for r in nzrange(A, col)
            # println(rowvals(A)[r], ' ', col, ' ',  nonzeros(A)[r]);
            # res = rowvals(A)[r] + col + nonzeros(A)[r]
            push!(xx,rowvals(A)[r]);
            push!(yy,col);
            push!(vv,nonzeros(A)[r]);
        end
    end
end
@btime printnz1(a)
@btime print_nz(a)

7.450 μs (265 allocations: 32.41 KiB)
8.467 μs (262 allocations: 26.45 KiB)

呜呜呜

感谢两位。速度快了很多。