# Nonzero element positions of a matrix

Let

m={{1, 2, 0}, {4, 0, 9}};


I want to find the position of every nonzero element of the above matrix. The code

SparseArray[m]["NonzeroPositions"]


returns

{{1, 1}, {1, 2}, {2, 1}, {2, 3}}


I want the output will be something like this

{{1, 2}, {1, 3}}


that is every element of the output is a list of the corresponding columns of nonzero elements in each row. How do I modify the code?

• GatherBy[SparseArray[m]["NonzeroPositions"], First][[All, All, 2]] Commented Mar 27, 2016 at 23:59
• or (SparseArray[#]["NonzeroPositions"] & /@ m)[[;; , ;; , 1]] Commented Mar 28, 2016 at 6:15

Update: The property "AdjacencyLists" gives what you need:

SparseArray[m]["AdjacencyLists"]


{{1, 2}, {1, 3}}

This approach, unlike the one using GatherBy in the original post, gives the empty set {} for the rows consisting entirely of zeros:

SparseArray[{{1, 2, 0}, {0, 0, 0}, {4, 0, 9}}]["AdjacencyLists"]


{{1, 2}, {}, {1, 3}}

Original post:

m = {{1, 2, 0}, {4, 0, 9}};
sa = SparseArray[m]["NonzeroPositions"];
GatherBy[sa, First][[All, All, -1]]


{{1, 2}, {1, 3}}

If the matrix isn't that sparse, then Pick may be a more efficient idea:

Pick[Range@Length@m[[1]], #, 0] & /@ UnitStep@-m

m = {{1, 2, 0}, {4, 0, 9}};

Flatten @* Values @* KeyDrop[0] @* PositionIndex /@ m


{1, 2}, {1, 3}}

Using SequencePosition:

First /@ SequencePosition[#, {Except[0]}] & /@ m


{{1, 2}, {1, 3}}

Using Position, Condition and Table:

f = Table[Flatten@Position[#[[i]], x_ /; x != 0], {i, Length@#}] &;

f@m

(*{{1, 2}, {1, 3}}*)


Or using Position, Condition and Range:

Flatten@*Transpose /@ (Position[m[[#]], x_ /; x != 0] & /@ Range[Length@m])

(*{{1, 2}, {1, 3}}*)


One can use e.g. SplitBy[list, First] way:

SplitBy[ SparseArray[m]["NonzeroPositions"], First][[All, 2]]

 {{1, 2}, {2, 3}}


Using SelectIndices by Taliesin Beynon

SelectPositions = ResourceFunction["SelectIndices"];

m = {{1, 2, 0}, {4, 0, 9}};

SelectPositions[UnequalTo @ 0] /@ m


{{1, 2}, {1, 3}}

m = {{1, 2, 0}, {4, 0, 9}};


Using Array and Cases :

 f1 = Map[Cases[Rule[a_, b_] /; b > 0 :> Last@a]];


{{1, 2}, {1, 3}}