Finding column indices of nonzero elements in a sparse matrix

Is there any julia way to find column indices of nonzero elements in a sparse matrix ?
I mean something that nzrange(A,j) does, but here j is the row index

1 Like

Based on your description, I am not quite sure I understand what you want. Consider the following sparse matrix

julia> A = sparse([1 2 0; 0 0 3; 0 4 0])
3Γ—3 SparseMatrixCSC{Int64, Int64} with 4 stored entries:
 1  2  β‹…
 β‹…  β‹…  3
 β‹…  4  β‹…

What should the desired outcome be in this example?

1 Like

Does this produce the required result:
unique(rowvals(permutedims(A)))

@rafael.guerra No this doesnt produce the required result.

@zdenek_hurak
what i wanted was something like this,

A = sparse([1 2 0 ;0 3 0 ;0 0 4])
julia> nzrange(sparse(A'),1)
1:2
julia> nzrange(sparse(A'),2)
3:3


I wished to know if there is way to avoid transposing and get resuts as nzrange applied on the rows of sparse matrix

I have a rough way of doing this, Just wish to know if there is more efficient way.

julia> A = sparse([1 2 0 ;0 3 0 ;0 0 4])
3Γ—3 SparseMatrixCSC{Int64, Int64} with 4 stored entries:
 1  2  β‹…
 β‹…  3  β‹…
 β‹…  β‹…  4

(Is,Js,Vs)=findnz(A)
julia> a = sparse(Js,Is,Vs,size(A,2),size(A,1))
3Γ—3 SparseMatrixCSC{Int64, Int64} with 4 stored entries:
 1  β‹…  β‹…
 2  3  β‹…
 β‹…  β‹…  4

This gives

julia> nzrange(a,1)
1:2

julia> nzrange(a,2)
3:3

This may do what you want, assuming it is correct to get contiguous ranges:

julia> using SparseArrays

julia> A = sparse([1 2 0 ;0 3 0 ;0 0 4]);

julia> findnzbyrow(A,row) = (x->findfirst(x):findlast(x))(findnz(A)[1] .== row)
findnzbyrow (generic function with 1 method)

julia> findnzbyrow(A,1)
1:2

julia> findnzbyrow(A,2)
3:3

This is better than transposing by hand, which probably makes copies. However, it’s slightly clunky because the findlast repeats some of the effort of findfirst. There may be cool ways to avoid this, but you could always write your own findfirstandlast. Also depends on your use case, because it’s possible you don’t need ranges at all, and can use the bitvector produced by findnz(A)[1] .== row.

EDIT: In general I don’t think you can expect to get contiguous ranges for the original A, unless you know that your data will be arranged properly. So it’s just plain better to use bitvectors if you can. Your hand transpose will give contiguous ranges appropriate for that matrix.