# Delete zero rows in a matrix

If there is a matrix with some of its rows equal to zero: (its zero rows are randomly distributed and does not have an ordered arrangement): same as:

m={{1,2,I},{0,0,0},{I,I,3},{2,6,I},{0,0,0},{0,0,0},{1,6,4},{0,0,0},{1,4,5}}


How can I have a mm matrix without any zero rows and all its rows are m's rows

mm={{1,2,I},{I,I,3},{2,6,I},{1,6,4},{1,4,5}}

• Cases[m, Except@{0 ..}] seems the most natural way to me, but probably not the most efficient Aug 6, 2015 at 11:50
• I expect some variation of Select[m, Norm[#] > 0&] to perform better but I haven't tested it. Aug 6, 2015 at 12:01
• Ok, thanks, Both of them work well. Aug 6, 2015 at 12:08
• DeleteCases[m, {0 ..}] should work. Aug 6, 2015 at 12:21
• m /. {0 ..} -> Sequence[] Aug 6, 2015 at 17:11

You could use:

Select[m,#!={0,0,0}&]


Where #!={0,0,0}& is a pure function that returns True for any list not equal to the list of three 0's.

• In which case, you should accept it by clicking the tick-mark next to the upvote arrows. Aug 6, 2015 at 12:13
• Yes, I know for accepting an answer, but I have heard not soon accepting an answer. Because of existing a time to others for present their answers. Aug 6, 2015 at 12:48
• @JohMcGee - A more general form using Select would be Select[m, FreeQ[#, {0 ..}] &] Aug 6, 2015 at 14:02

This s/b considerably faster for large cases:

#[[Union[SparseArray[#]["NonzeroPositions"][[All, 1]]]]] &@array


and this is even faster:

Replace[#, ConstantArray[0, Length@#[[1]]] -> Sequence[], {1}] &@array


and about the same as latter:

DeleteCases[#, ConstantArray[0, Length@#[[1]]]]&@array


Try this:

m = {{1, 2, I}, {0, 0, 0}, {I, I, 3}, {2, 6, I}, {0, 0, 0}, {0, 0,
0}, {1, 6, 4}, {0, 0, 0}, {1, 4, 5}};

DeleteCases[m, {0 ..}, Infinity]


$\left( \begin{array}{ccc} 1 & 2 & i \\ i & i & 3 \\ 2 & 6 & i \\ 1 & 6 & 4 \\ 1 & 4 & 5 \\ \end{array} \right)$

A method that should go well with purely numerical matrices (at least when m has significantly fewer columns than rows) is

Pick[m, Unitize[Abs[m].ConstantArray[1., cols]], 1]


It vectorizes the row checks and does not unpack PackedArrays.

Delete[m, Position[m, ConstantArray[0, Length[First[m]]], {1}]]


Or just

Delete[m, Position[m, {0 ..}, {1}]]

m = {{1, 2, I}, {0}, {I, I, 3}, {2, 6, I}, {0, 0, 0}, {0, 0, 0, 0}, {1, 6, 4}, {0, 0, 0}, {1, 4, 5}};


Using SequenceSplit (new in 11.3)

Join @@ SequenceSplit[m, {{0 ..}}]


{{1, 2, I}, {I, I, 3}, {2, 6, I}, {1, 6, 4}, {1, 4, 5}}

Using ReplaceAll and ContainsOnly:

m = {{1, 2, I}, {0, 0, 0}, {I, I, 3},
{2, 6, I}, {0, 0, 0}, {0, 0, 0},
{1, 6, 4}, {0, 0, 0}, {1, 4, 5}};
mm = {{1, 2, I}, {I, I, 3}, {2, 6, I}, {1, 6, 4}, {1, 4, 5}};

(m /. x_List /; ContainsOnly[x, {0}] :> Nothing) === mm

(*True*)


Or using ZeroArrayQ:

(m /. x_ /; LinearAlgebraPrivateZeroArrayQ[x] :> Nothing) === mm

(*True*)


I am adding some contributions. As far as I checked there's no overlap with the suggestions so far. If someone spots something, I would appreciate a comment and I will remove the duplicate.

I am grabbing from @E. Chan-López

m = {{1, 2, I}, {0, 0, 0}, {I, I, 3}, {2, 6, I}, {0, 0, 0}, {0, 0,
0}, {1, 6, 4}, {0, 0, 0}, {1, 4, 5}};
mm = {{1, 2, I}, {I, I, 3}, {2, 6, I}, {1, 6, 4}, {1, 4, 5}};


All of the following return True

DeleteElements[m, {0 ..} :> Infinity];
mm === %
m //. {0 ..} :> Unevaluated[## &[]];
mm === %
m //. {0 ..} -> Sequence[];
mm === %
m //. {0 ..} :> Nothing;
mm === %
Delete[Position[{0 ..}]@m]@m;
mm === %
Select[#, UnequalTo[0]] & /@ m //. {} :> Nothing;
mm === %
Cases[m, Except@{0 ..}];
mm === %
Select[m, x |-> FreeQ[x, {0 ..}]];
mm == %
Pick[m, Total /@ Unitize@m, Except[0 | _List]]
mm == %


Edit I am adding this variant which was suggested by the fellow 10-fold ways @ E. Chan-López in the comments

Pick[m, ! MatchQ[#, {0 ..}] & /@ m]

• An alternative using Pick: Pick[m, ! MatchQ[#, {0 ..}] & /@ m] :-) Dec 28, 2023 at 6:03
• @E.Chan-López thanks a lot mate :-) Updated
– bmf
Dec 28, 2023 at 13:52

Using DiscreteDelta:

m = {{1, 2, I}, {0, 0, 0}, {I, I, 3}, {2, 6, I}, {0, 0, 0}, {0, 0,
0}, {1, 6, 4}, {0, 0, 0}, {1, 4, 5}};

Pick[m, DiscreteDelta @@@ m, 0]


or

Select[EqualTo[0]@*Apply[DiscreteDelta]][m]


Result:

{{1, 2, I}, {I, I, 3}, {2, 6, I}, {1, 6, 4}, {1, 4, 5}}

• +1 - I didn't even know this function :)
– eldo
Feb 19 at 13:33
• Also explore the KroneckerDelta. @eldo
– Syed
Feb 19 at 13:37

And if you want to delete cases where a certain column is zero, say the last column, this works:

Select[m,#!={#,#,0}&]

• First of all, this is not the point in this topic, you can find an appropriate one and add the answer there. Secondly, this is very hairy, such function # != {#, #, 0} &@{1, 1, 0} is left unevaluated.
– Kuba
Apr 4, 2017 at 8:07