# 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.