# How to extract certain rows satisfying a condition?

I have three columns - P1,P2,M and 411935 rows. I want to extract only those rows which satisfy P1>=P2>=0.25*M. How can I do it?

Select[yourTable, #[[1]]>=#[[2]]>=(0.25*#[[3]])&]


If runtime is a major concern to you, you could use this Pick along with vectorized integer arithmetic instead:

yourTable = RandomReal[{-1, 1}, {411935, 3}];
aa = Select[
yourTable,
#[[1]] >= #[[2]] >= (0.25*#[[3]]) &
]; // RepeatedTiming // First
bb = Pick[
yourTable,
Times@@UnitStep[Differences[{0.25,1.,1.} Transpose[yourTable][[{3,2,1}]]]],
1
]; // RepeatedTiming // First
aa == bb


0.76

0.0142

True

If your columns are already given as vector P1, P2, and M, then you can skip the costly transposition to get the transposed result of the above:

{P1, P2, M} = Transpose[yourTable];
(
picker = UnitStep[Subtract[P1, P2]] UnitStep[Subtract[P2, 0.25 M]];
{nP1, nP2, nM} = Map[Pick[#, picker, 1] &, {P1, P2, M}];
) // RepeatedTiming // First

{nP1, nP2, nM} == Transpose[bb]


0.0075

True

Here's a variation of @Henrik's Pick approach that avoids Transpose:

cc = Pick[
yourTable,
UnitStep[yourTable . {{1,0}, {-1,1}, {0,-.25}}] . {1,1},
2
]; //RepeatedTiming


{0.010, Null}

bb = Pick[
yourTable,
Times@@UnitStep[Differences[{0.25,1.,1.} Transpose[yourTable][[{3,2,1}]]]],
1
]; // RepeatedTiming

bb === cc


{0.020, Null}

True

• Ah, very good improvement, indeed! In particular, I pretty much like how you replaced Times by a Dot. Plus, this is much short to type.^^ Aug 31 '18 at 11:34
• @HenrikSchumacher Exactly. I saw those Times operations, and thought figuring out how to use Dot instead should provide a nice speed up. Aug 31 '18 at 11:39
• Surprisingly, I found that picker = UnitStep[P1 - P2] + UnitStep[P2 - 0.25 M]; {nP1, nP2, nM} = Map[Pick[#, picker, 2] &, {P1, P2, M}]; is not faster than picker = UnitStep[P1 - P2] UnitStep[P2 - 0.25 M]; {nP1, nP2, nM} = Map[Pick[#, picker, 1] &, {P1, P2, M}]; on my machine. But anyways, the Dot  saves a transposition. Aug 31 '18 at 11:49
data = Pick[DATA,
Table[p1[[i]] >= p2[[i]] >= 0.25*M[[i]], {i, 411935}]]


Thank you all for sharing your ideas. I used the above by combining your ideas and it worked.