11
$\begingroup$

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}}
$\endgroup$
  • 3
    $\begingroup$ Cases[m, Except@{0 ..}] seems the most natural way to me, but probably not the most efficient $\endgroup$ – Dr. belisarius Aug 6 '15 at 11:50
  • 2
    $\begingroup$ I expect some variation of Select[m, Norm[#] > 0&] to perform better but I haven't tested it. $\endgroup$ – Szabolcs Aug 6 '15 at 12:01
  • $\begingroup$ Ok, thanks, Both of them work well. $\endgroup$ – Unbelievable Aug 6 '15 at 12:08
  • 4
    $\begingroup$ DeleteCases[m, {0 ..}] should work. $\endgroup$ – J. M. is away Aug 6 '15 at 12:21
  • $\begingroup$ m /. {0 ..} -> Sequence[] $\endgroup$ – Algohi Aug 6 '15 at 17:11
14
$\begingroup$

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.

$\endgroup$
  • $\begingroup$ In which case, you should accept it by clicking the tick-mark next to the upvote arrows. $\endgroup$ – Patrick Stevens Aug 6 '15 at 12:13
  • $\begingroup$ 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. $\endgroup$ – Unbelievable Aug 6 '15 at 12:48
  • 1
    $\begingroup$ @JohMcGee - A more general form using Select would be Select[m, FreeQ[#, {0 ..}] &] $\endgroup$ – Bob Hanlon Aug 6 '15 at 14:02
5
$\begingroup$

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
$\endgroup$
4
$\begingroup$

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)$

$\endgroup$
2
$\begingroup$

And if you want to delete cases where a certain column is zero, say the last column, this works: Select[m,#!={#,#,0}&]

$\endgroup$
  • 1
    $\begingroup$ 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. $\endgroup$ – Kuba Apr 4 '17 at 8:07
2
$\begingroup$
Delete[m, Position[m, ConstantArray[0, Length[First[m]]], {1}]]

Or just

Delete[m, Position[m, {0 ..}, {1}]]
$\endgroup$
2
$\begingroup$

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.