3
$\begingroup$

I have a list like the following list of pairs:

{{0., 2.}, {0.05, 2.01597}, {0.1, 2.03223}, {0.15, 2.04913}, {0.2, 
 2.06704}, {0.25, 2.08641}, {0.3, 2.10784}, {0.35, 2.13212}, {0.4, 
 2.16039}, {0.45, 2.19429}, {0.5, 2.23637}, {0.55, 2.29066}, {0.6, 
 2.36381}, {0.65, 2.46671}, {0.7, 2.61553}, {0.75, 4.82404}, {0.8, 
 1.07405}, {0.85, 1.30513}, {0.9, 1.47802}, {0.95, 1.59783}, {1., 
 1.68171}, {1.05, 1.74284}, {1.1, 1.78939}, {1.15, 1.82631}, {1.2, 
 1.85668}, {1.25, 1.88246}, {1.3, 1.90497}, {1.35, 1.92511}, {1.4, 
 1.94356}, {1.45, 1.96083}, {1.5, 1.97732}, {1.55, 1.99338}, {1.6, 
 2.00931}, {1.65, 2.02541}, {1.7, 2.04201}, {1.75, 2.05944}, {1.8, 
 2.07814}, {1.85, 2.09863}, {1.9, 2.12161}, {1.95, 2.14806}, {2., 
 2.17937}, {2.05, 2.21766}, {2.1, 2.26625}, {2.15, 2.33051}, {2.2, 
 2.41936}, {2.25, 2.54689}, {2.3, 2.73003}, {2.35, 4.96848}, {2.4, 
 1.2151}, {2.45, 1.41347}, {2.5, 1.55331}, {2.55, 1.65021}, {2.6, 
 1.71956}, {2.65, 1.77142}, {2.7, 1.81189}, {2.75, 1.8447}, {2.8, 
 1.8722}, {2.85, 1.89594}, {2.9, 1.91697}, {2.95, 1.93606}, {3., 
 1.95377}, {3.05, 1.97054}, {3.1, 1.98673}}

I want to select only those elements where the second pair element is between 1.0 and 2.0. Can you show me how to do this?

$\endgroup$

closed as off-topic by Bob Hanlon, MarcoB, C. E., LouisB, march Oct 17 at 15:51

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This question arises due to a simple mistake such as a trivial syntax error, incorrect capitalization, spelling mistake, or other typographical error and is unlikely to help any future visitors, or else it is easily found in the documentation." – Bob Hanlon, MarcoB, C. E., LouisB, march
If this question can be reworded to fit the rules in the help center, please edit the question.

5
$\begingroup$
data = {{0., 2.}, {0.05, 2.01597}, {0.1, 2.03223}, {0.15, 
2.04913}, {0.2, 2.06704}, {0.25, 2.08641}, {0.3, 2.10784}, {0.35, 
2.13212}, {0.4, 2.16039}, {0.45, 2.19429}, {0.5, 2.23637}, {0.55, 
2.29066}, {0.6, 2.36381}, {0.65, 2.46671}, {0.7, 2.61553}, {0.75, 
4.82404}, {0.8, 1.07405}, {0.85, 1.30513}, {0.9, 1.47802}, {0.95, 
1.59783}, {1., 1.68171}, {1.05, 1.74284}, {1.1, 1.78939}, {1.15, 
1.82631}, {1.2, 1.85668}, {1.25, 1.88246}, {1.3, 1.90497}, {1.35, 
1.92511}, {1.4, 1.94356}, {1.45, 1.96083}, {1.5, 1.97732}, {1.55, 
1.99338}, {1.6, 2.00931}, {1.65, 2.02541}, {1.7, 2.04201}, {1.75, 
2.05944}, {1.8, 2.07814}, {1.85, 2.09863}, {1.9, 2.12161}, {1.95, 
2.14806}, {2., 2.17937}, {2.05, 2.21766}, {2.1, 2.26625}, {2.15, 
2.33051}, {2.2, 2.41936}, {2.25, 2.54689}, {2.3, 2.73003}, {2.35, 
4.96848}, {2.4, 1.2151}, {2.45, 1.41347}, {2.5, 1.55331}, {2.55, 
1.65021}, {2.6, 1.71956}, {2.65, 1.77142}, {2.7, 1.81189}, {2.75, 
1.8447}, {2.8, 1.8722}, {2.85, 1.89594}, {2.9, 1.91697}, {2.95, 
1.93606}, {3., 1.95377}, {3.05, 1.97054}, {3.1, 1.98673}};

Select[data, 1.0 < #[[2]] < 2.0 &]
(*Another method*) Cases[data, {x_, y_} /; 1.0 < y < 2.0] == %
(*Another method*) DeleteCases[If[1.0 < #2 < 2.0, {##}] & @@@ data, Null] == %%

{{0.8, 1.07405}, {0.85, 1.30513}, {0.9, 1.47802}, {0.95, 1.59783}, {1., 1.68171}, {1.05, 1.74284}, {1.1, 1.78939}, {1.15, 1.82631}, {1.2, 1.85668}, {1.25, 1.88246}, {1.3, 1.90497}, {1.35, 1.92511}, {1.4, 1.94356}, {1.45, 1.96083}, {1.5, 1.97732}, {1.55, 1.99338}, {2.4, 1.2151}, {2.45, 1.41347}, {2.5, 1.55331}, {2.55, 1.65021}, {2.6, 1.71956}, {2.65, 1.77142}, {2.7, 1.81189}, {2.75, 1.8447}, {2.8, 1.8722}, {2.85, 1.89594}, {2.9, 1.91697}, {2.95, 1.93606}, {3., 1.95377}, {3.05, 1.97054}, {3.1, 1.98673}}

True

True

If you're using version 10.2 or above, this should work (I say should because I'm on version 10.1 and thus can't test it.)

If[1.0 < #2 < 2.0, {##}, Nothing] & @@@ data
$\endgroup$
  • 2
    $\begingroup$ Depending on how the OP wants to treat the endpoints, Pick[data, UnitBox[data[[All, 2]] - 1.5], 1] will work, too. It's equivalent with Cases[data, {x_, y_} /; 1.0 < y <= 2.0]. $\endgroup$ – march Oct 15 at 22:12
  • $\begingroup$ Cases works perfectly and also allows me to put bounds on x. Cases[data, {x_, y_} /; 1.0 < y < 5.0 && 0.77 < x < 2.36] $\endgroup$ – Klandgren Oct 15 at 22:51
4
$\begingroup$

Select[data, Last /* Between[{1, 2}]] will do the trick and has the benefit of being readable.

$\endgroup$
3
$\begingroup$

Pick[data, Unitize[Clip[data[[All, 2]], {1, 2}, {0, 0}]], 1]

This should be faster than methods posted or in comments so far.

$\endgroup$
3
$\begingroup$

An alternative way to use Pick:

With[{d = data[[All, 2]]}, 
  Pick[data, UnitStep[d - 1] (1 - UnitStep[d - 2]), 1]]

% == Select[data, 1.0 < #[[2]] < 2.0 &]

True

You can also useBinLists:

BinLists[data, {{-∞, ∞}}, {{1 + $MachineEpsilon, 2 - $MachineEpsilon}}][[1, 1]]

% == Select[data, 1.0 < #[[2]] < 2.0 &]

True

Although not as fast as Pick, BinLists is much faster than Select and Cases for large lists of pairs.

Timings: On Wolfram Cloud:

$Version

"12.0.0 for Linux x86 (64-bit) (April 7, 2019)"

SeedRandom[1]
data = RandomReal[3, {500000, 2}];

pick1 = With[{d = data[[All, 2]]}, Pick[data, 
          UnitStep[d - 1.] (1 - UnitStep[d - 2.]), 1]]; // RepeatedTiming // First

0.015

pick2 = Pick[data, Unitize[Clip[data[[All, 2]], {1 + $MachineEpsilon, 
        2 - $MachineEpsilon}, {0, 0}]], 1] ; // RepeatedTiming // First

0.018

bl = BinLists[data, {{-∞, ∞}}, 
    {{1 + $MachineEpsilon, 2 - $MachineEpsilon}}][[1, 1]]; // RepeatedTiming // First

0.029

cas = Cases[data, {x_, y_} /; 1.0 < y < 2.0] ; // RepeatedTiming // First

0.713

if = If[1.0 < #2 < 2.0, {##}, Nothing] & @@@ data; // RepeatedTiming // First

0.8093

delc = DeleteCases[If[1.0 < #2 < 2.0, {##}] & @@@ data, Null]; // 
  RepeatedTiming//First

0.850

sel1 = Select[data, 1.0 < #[[2]] < 2.0 &]; // RepeatedTiming // First

0.85

sel2 = Select[data, Last /* Between[{1, 2}]] ; // RepeatedTiming// First

1.5

pick1 == pick2 == bl == cas == if == delc == sel1 == sel2

True

where I used a variation of ciao's proposed method to get pick2; sel1. cas, if and delc are obtained using methods from ThatGravityGuy's answer; and sel2 is obtained using CarbonFlambe's suggested method for Select.

$\endgroup$

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