3
$\begingroup$

Let $(x_{min},x_{max})$ and $(y_{min},y_{max})$ represent lowerbound and upperbound acceptable values for some coordinate $c_i$.

Setting $x_{min} = y_{min} = 1$ & $x_{max} = y_{max} = 9$, how can I take a list of values, e.g.:

val = {{0, 10}, {2, 10}, {4, 4}, {5, 6}, {10, 4}};

and use DeleteCases to get rid of coordinates such as {0, 10}, {2,10}, & {10,4} (the examples in the above list) where either the $x$ or $y$ component of a pair is outside of the specified upper and lower bounds for acceptable values? Is DeleteCases an appropriate tool for large arrays?

$\endgroup$
0

2 Answers 2

6
$\begingroup$

You can achieve the same end with DeleteCases or Cases.

f signals a coordinate that is out of bounds.

g signals that a coordinate is in bounds.

f[n_] := n < 1 \[Or] n > 9
g[n_] := 1 <= n <= 9

Four ways to filter out the outlying points:

v[k] generates 10^k values between {0, 0} and {10, 10})

v[k_] := Table[{r, r}, {10^k}];
  1. Delete the points that have an out-of-bounds coordinate.

    DeleteCases[v[k], {x_, y_} /; f[x] \[Or] f[y]]
    
  2. Delete the points that are not in-bounds.

    DeleteCases[v[k], {x_, y_} /; \[Not] (g[x] \[And] g[y])]
    
  3. Keep points that are not out-of-bounds.

    Cases[v[k], {x_, y_} /; \[Not] (f[x] \[Or] f[y])]
    
  4. Keep points that are in-bounds.

    Cases[v[k], {x_, y_} /; (g[x] \[And] g[y])]
    

Timings

    r = Table[{AbsoluteTiming[DeleteCases[v[k], {x_, y_} /; f[x] \[Or] f[y]];],
          AbsoluteTiming[DeleteCases[v[k], {x_, y_} /; \[Not] (g[x] \[And]g[y])];], 
          AbsoluteTiming[Cases[v[k], {x_, y_} /; \[Not] (f[x] \[Or] f[y])];],
          AbsoluteTiming[Cases[v[k], {x_, y_} /; (g[x] \[And] g[y])];]}, {k,  3, 7}]
    Grid@Prepend[ r[[All, All, 1]], {"Delete f", "Delete not-g", "Cases not-f", "Cases g"}]

The results with DeleteCases and Cases (from 10^3 to 10^7 points) show that DeleteCases with function g gives the fastest analysis.

results

$\endgroup$
2
$\begingroup$

An alternative is to use Select to retain only those elements you desire:

val = {{0, 10}, {2, 10}, {4, 4}, {5, 6}, {10, 4}}; 
Select[val, 1 <= First[#] <= 9 && 1 <= Last[#] <= 9 &]

{{4, 4}, {5, 6}}

In this case, all those with values outside the specified ranges are removed, leaving only the desired pairs.

$\endgroup$

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