4
$\begingroup$

I have some processed data, which are basically a collection of ordered pairs in the form:

{{x1, y1}, {x2, y2}, ..., {xn, yn}}

Ordered pairs which have either a zero $x$ or $y$ component are not physically meaningful, and should be deleted from the data. I can't for the life of me figure out how to delete these points. I've tried DeleteCases, Position, Select, Cases, etc. and none of them work for my application.

$\endgroup$
5
$\begingroup$

The best choice is an appropriate use of DeleteCases. I'd recommend DeleteCases with a pattern {___, 0,___} (see BlankNullSequence) since it can remove zeros in more general lists than of those of length 2, moreover it is resonably faster than {a_, 0} | {0, a_}, on the other hand it is slower than {_, 0} | { 0, _}. One can use also {___, 0 | 0., ___} in any case. Let's demonstrate two cases :

list1 = RandomInteger[{-5, 5}, {10^5, 2}];
list3 = RandomInteger[{-5, 5}, {10^6, 2}];


DeleteCases[list3, {a_, 0} | {0, a_}]; // AbsoluteTiming // First
DeleteCases[list3, {_, 0} | {0, _}]; // AbsoluteTiming // First
DeleteCases[list3, {___, 0, ___}]; // AbsoluteTiming // First
0.203125
0.156250
0.171875
DeleteCases[list3, {a_, 0} | {0, a_}]; // AbsoluteTiming // First
DeleteCases[list3, {_, 0} | {0, _}]; // AbsoluteTiming // First
DeleteCases[list3, {___, 0, ___}]; // AbsoluteTiming // First
2.000000
1.609375
1.765625
$\endgroup$
  • $\begingroup$ Well, not really. The fastest seems to be DeleteCases[list, {_, 0} | {0, _}]. $\endgroup$ – xzczd Apr 8 '13 at 6:46
  • $\begingroup$ Where are your tests ? Have you done them ? I've tried more lists and {___, 0, ___} has been faster than {a_, 0} | {0, a_} everytime. $\endgroup$ – Artes Apr 8 '13 at 6:49
  • $\begingroup$ ok, I added another case {_, 0} | { 0, _} but one can delete 0 in much longer lists with {___, 0, ___} $\endgroup$ – Artes Apr 8 '13 at 7:01
  • $\begingroup$ I've added a snapshot to my answer. It seems that {_, 0} | {0, _} and {a_, 0} | {0, a_} are different… $\endgroup$ – xzczd Apr 8 '13 at 7:01
5
$\begingroup$

Don't forget to handle exact and numeric 0 too! The pattern matcher in any case where the zero is specified as the integer 0 (like in Select[list, FreeQ[#, 0] &]) won't recognize a numerical zero, as 0 =!= 0.0.

list = {{1, 1}, {2, 0.}, {0, 4}, {0, 0.}, {2, 2}, {3, 4}, {1, 0.}, {0, 3}};

list /. {___, 0 | 0., ___} :> Sequence[]
{{1, 1}, {2, 2}, {3, 4}}

For even more robustness:

list /. {___, _?PossibleZeroQ, ___} :> Sequence[]

or for testing numerical value (possible other than zero), use Equal explicitly:

list /. {___, _?(# == 0. &), ___} :> Sequence[]

This is necessary as matching with Replace uses MatchQ which tests pattern identity and therefore misses equal numerical values:

0. /. {0 -> True, 0. -> False}                       (* ==> False *)
{MatchQ[0., 0], MatchQ[0.0000000000000000000, 0.]}   (* ==> {False, False} *)
{SameQ[0., 0], SameQ[0.0000000000000000000, 0.]}     (* ==> {False, True} *)
{Equal[0., 0], Equal[0.0000000000000000000, 0.]}     (* ==> {True, True} *)
{PossibleZeroQ@0, PossibleZeroQ@0., PossibleZeroQ@0.0000000000000000000}
                                                     (* ==> {True, True, True} *)
$\endgroup$
  • $\begingroup$ OK, I forgot it completly ORZ… $\endgroup$ – xzczd Apr 8 '13 at 6:54
  • $\begingroup$ I actually remembered this after I posted my answer but was too lazy to incorporate it. Nice one. $\endgroup$ – RunnyKine Apr 8 '13 at 6:58
  • 1
    $\begingroup$ For robustness you should be using Equal. Some values that you would want to match do not: MatchQ[0.0000000000000000000, 0 | 0.]. $\endgroup$ – Mr.Wizard Apr 8 '13 at 10:29
  • $\begingroup$ @Mr.W True that, thanks. $\endgroup$ – István Zachar Apr 8 '13 at 10:54
  • $\begingroup$ @Mr.W Please see edit. I wonder why MatchQ[0.0000000000000000000, 0.] does not fall back to use SameQ. What exactly MatchQ uses if it is not SameQ in such cases? $\endgroup$ – István Zachar Apr 8 '13 at 11:21
3
$\begingroup$

DeleteCases, Position, Select, Cases all works:

list = {{1, 1}, {2, 0}, {0, 4}, {0, 0}};

DeleteCases[list, {a_, 0} | {0, a_}]
Extract[list, Position[list2, {a_ /; a != 0, b_ /; b != 0}]]
Select[list, #[[1]] != 0 && #[[2]] != 0 &]
Select[list, FreeQ[#, 0] &]
Select[list, ! MemberQ[#, 0] &]
Cases[list, Except[{_, 0} | {0, _}]]


(*
{{1,1}}
{{1,1}}
{{1,1}}
{{1,1}}
{{1,1}}
{{1,1}}
*)

Here's a speed test for the solutions given by RunnyKine, Artes and me:

enter image description here


OK, I had been completely forgot the 0. before István Zachar mentioned it ORZ. For completeness:

list2 = {{1, 1}, {2, 0}, {0, 4}, {0, 0}, {0, 0.}, {0., 3}, {4, 0.}};

DeleteCases[list2, {a_, 0 | 0.} | {0 | 0., a_}]
Extract[list2, Position[list2, {a_ /; a != 0, b_ /; b != 0}]]
Select[list2, #[[1]] != 0 && #[[2]] != 0 &]
Select[list2, FreeQ[#, 0 | 0.] &]
Select[list2, ! MemberQ[#, 0 | 0.] &]
Cases[list2, Except[{_, 0 | 0.} | {0 | 0., _}]]

(*
{{1,1}}
{{1,1}}
{{1,1}}
{{1,1}}
{{1,1}}
{{1,1}}
*)

Notice that the modification of the code is only necessary for the pattern match, so my second and third solutions with Unequal(!=) are not changed.

$\endgroup$
3
$\begingroup$

This is not general, but because you are removing zeros, you can use tricks like this:

Pick[list, Unitize[Times @@ Transpose @ list], 1]
$\endgroup$
2
$\begingroup$

Another way, @xzczd covered most of them.

list = {{1, 1}, {2, 0}, {0, 4}, {0, 0}, {2, 2}, {3, 4}, {1, 0}, {0, 3}};

list /. {x_, 0} -> Sequence[] /. {0, y_} -> Sequence[]

OR you could just do

list /. ({x_, 0} | {0, y_}) -> Sequence[]

AND for completeness as suggested by @Istvan

list /. ({x_, 0 | 0.} | {0 | 0., y_}) -> Sequence[]

gives:

{{1, 1}, {2, 2}, {3, 4}}
$\endgroup$
-1
$\begingroup$

list = {A,B,C,D,E,F}. Using DeleteCases[list, A|C|E] returns {B,D,F}. Also note that "0" is not the same as "0."

$\endgroup$
  • 1
    $\begingroup$ I believe that the OP wishes to delete ordered pairs, not individual elements. $\endgroup$ – bbgodfrey Jun 25 '15 at 21:26

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.