# Removing zero values from ordered pairs

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.

-
Possible duplicates: (14122), (15907) and related: (5149), (6994) – Mr.Wizard Apr 8 '13 at 10:19

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

-
I believe that the OP wishes to delete ordered pairs, not individual elements. – bbgodfrey Jun 25 '15 at 21:26

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} *)

-
OK, I forgot it completly ORZ… – xzczd Apr 8 '13 at 6:54
I actually remembered this after I posted my answer but was too lazy to incorporate it. Nice one. – RunnyKine Apr 8 '13 at 6:58
For robustness you should be using Equal. Some values that you would want to match do not: MatchQ[0.0000000000000000000, 0 | 0.]. – Mr.Wizard Apr 8 '13 at 10:29
@Mr.W True that, thanks. – István Zachar Apr 8 '13 at 10:54
@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? – István Zachar Apr 8 '13 at 11:21

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

Pick[list, Unitize[Times @@ Transpose @ list], 1]

-

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:

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.

-

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

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

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}}

-