2
$\begingroup$

I'm essentially doing coin flips, using RandomReal to populate a bunch of lists, each with 8 elements. I then want to select only those lists for which all elements are greater than a certain number, e.g. .5.

So far I have this:

class = RandomReal[1, {100, 8}];
pass = Select[class, #[[1]] > (.5) &]

but this doesn't work. I suspect a simple Select function would do the trick, but I can't seem to get the syntax right to test every element of the nested listed against a certain number and then only return those lists for which every element passes. Or indeed simply to return the number of sublists for which every element passes. Thanks.

$\endgroup$
5
  • $\begingroup$ Select[class, And @@ Thread[# > .5] &] $\endgroup$ Commented May 8, 2014 at 0:17
  • $\begingroup$ Conceptually, you want this: Select[class, And @@ Map[# > 0.5 &, #] &]. Performance-wise, you'd be better off with something like Select[class, Total[UnitStep[0.5 - #]] == 0 &]. $\endgroup$ Commented May 8, 2014 at 0:17
  • $\begingroup$ The Gods have answered so I might as well delete my answer, my answer was this: Pick[class,Times @@ UnitStep[#] == 1 & /@ (class - 0.5)] $\endgroup$
    – C. E.
    Commented May 8, 2014 at 0:18
  • 1
    $\begingroup$ @Pickett The intended effect of answering in comments isn't to preclude "real" answers, but to give some food for thought for the OP AND to other users that might want to elaborate a good post (in this case, for example doing some perf. comps, etc). Ref: meta.mathematica.stackexchange.com/q/1244/193 $\endgroup$ Commented May 8, 2014 at 0:25
  • 1
    $\begingroup$ Pick[#, Sign[(Min /@ #) - #2], 1] &[class, .5] probably about as fast as possible, change second argument obviously for limit. Properly returns those sublists where all members are greater as your OP states. $\endgroup$
    – ciao
    Commented May 8, 2014 at 7:49

7 Answers 7

10
$\begingroup$

Maybe I'm missing something but this seems like a straightforward application of Min:

SeedRandom[1]
class = RandomReal[1, {100, 5}];

Select[class, Min[#] > 0.5 &]
{{0.823403, 0.551229, 0.746259, 0.964339, 0.89009},
 {0.745146, 0.714426, 0.809069, 0.833149, 0.725859}}
$\endgroup$
3
$\begingroup$

This answer summarizes the answers given in the comments to this question. I have changed two parameter values to keep the output small. Since set the values of the two parameters with With, it will to restore the original values should that be desired.

With[{size = 4}, SeedRandom @ 42; class = RandomReal[1, {100, size}]];

With[{threshold = .6}, Column@Select[class, And @@ ((# > threshold &) /@ #) &]]

With[{threshold = .6}, Column@Select[class, And @@ Thread[# > threshold] &]]

With[{threshold = .6}, Column@Select[class, Total[UnitStep[threshold - #]] == 0 &]]

With[{threshold = .6}, Column@Pick[class, Times @@ UnitStep[#] == 1 & /@ (class - threshold)]]

All of the four above expressions return

{0.717287,0.754353,0.860349,0.996966}
{0.763037,0.631343,0.89637,0.621647}
$\endgroup$
3
$\begingroup$

Maybe it can be done also as follows:

Select[Select[#, # > 0.5 &] & /@ class, Length[#] == 8 &]
$\endgroup$
3
$\begingroup$

enter image description here

SeedRandom[3];
class = RandomReal[1, {100, 8}];
Select[AllTrue[# > 0.5 &]][class]

{{0.681735, 0.630934, 0.746274, 0.772147, 0.919485, 0.768809, 0.950752, 0.909879}, {0.939844, 0.556898, 0.828244, 0.687478, 0.558535, 0.707213, 0.961479, 0.636546}}

Often returns an empty list for such a high threshold. I had to experiment with SeedRandom value, but not for long.

$\endgroup$
2
$\begingroup$

Using GroupBy and Lookup:

class = RandomReal[1, {100, 8}];
Lookup[GroupBy[class, AllTrue[# > 0.5 &]], True, {}]

(*{{0.86521, 0.503485, 0.88936, 0.973814, 0.609053, 0.661455, 0.980263, 0.839613}, 
{0.982626, 0.848077, 0.595841, 0.685342, 0.771152, 0.801341, 0.638942, 0.537611}}*)
$\endgroup$
2
$\begingroup$

1. above

SeedRandom[3];
class = RandomReal[1, {100, 8}];

above[n_][x_] /; Min[x] > n := x
above[_][_] := Nothing

above[0.5] /@ class

{{0.681735, 0.630934, 0.746274, 0.772147, 0.919485, 0.768809, 0.950752, 0.909879}, {0.939844, 0.556898, 0.828244, 0.687478, 0.558535, 0.707213, 0.961479, 0.636546}}

above[0.6] /@ class

{{0.681735, 0.630934, 0.746274, 0.772147, 0.919485, 0.768809, 0.950752, 0.909879}}

above[0.7] /@ class

{}

2. Threshold

We can also use Threshold which zeros out matrix elements with absolute value LESS than n:

Select[FreeQ @ 0.] @ Threshold[class, 0.5]

{{0.681735, 0.630934, 0.746274, 0.772147, 0.919485, 0.768809, 0.950752, 0.909879}, {0.939844, 0.556898, 0.828244, 0.687478, 0.558535, 0.707213, 0.961479, 0.636546}}

To include a value of exactly 0.5 we can subtract a small number from n:

m = {{0.681, 0.630, 0.746, 0.5}, {0.681, 0.630, 0.746, 0.51}};

Threshold[m, 0.5]

{{0.681, 0.63, 0.746, 0.}, {0.681, 0.63, 0.746, 0.51}}

Threshold[m, 0.5 - 10^-10]

{{0.681, 0.63, 0.746, 0.5}, {0.681, 0.63, 0.746, 0.51}}

$\endgroup$
0
$\begingroup$
RandomReal[{1/2 + $MachineEpsilon,1|,{100,8}]

No testing needed.

$\endgroup$
2
  • 1
    $\begingroup$ Would there be any values below 0.5 ? I think the question is how to select such lists from randomly generated lists not how to generate a list with all values above a threshold. $\endgroup$
    – Syed
    Commented Apr 14, 2023 at 7:17
  • $\begingroup$ On that point, I opine that the question was uclear. Generation and selection were both mentioned. I had the impression that the questioner may not have realized that RandomReal could be range restricted to the stated goal of having only lists with values above 0.5. I concede that your interpretation is also reasonable. $\endgroup$
    – anon
    Commented Apr 14, 2023 at 17:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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