2
$\begingroup$

I am trying to do:

Select[minimus[[6]], #1[[2]] < (min[[6]] + emin[[6]]) &]

applied to all elements of minimus, min and emin. They all have the same Length, but minimus is a list of pair coordinates {{x1, y1}, {x2, y2}, ..., {xN, yN}} while both min and emin are lists of values.

I thought something like this would work:

Map[Select[minimus[[#2]], #1[[2]] < (min[[#2]] + emin[[#2]])&]&, Range[Length[minimus]]]

But it didn't...

Any thoughts?

$\endgroup$
3
  • 1
    $\begingroup$ Perhaps you can include a sample list with the expected output? $\endgroup$
    – march
    Apr 19, 2016 at 16:30
  • $\begingroup$ Anyway, maybe something like Function[{x}, Select[minimus[[x]], #1[[2]] < (min[[x]] + emin[[x]]) &] & /@ Range@Length@minimus. Or just Table[Select[minimus[[x]], #1[[2]] < (min[[x]] + emin[[x]]) &], {x, Length@minimus}]. $\endgroup$
    – march
    Apr 19, 2016 at 16:32
  • $\begingroup$ Select[minimus[[6]]... is selecting from two values, you sure ties is correct? See my answer if you need another thing. $\endgroup$
    – BlacKow
    Apr 19, 2016 at 16:43

3 Answers 3

8
$\begingroup$
Pick[minimus, UnitStep[min + emin - minimus[[;; , 2]]], 1]

or a pure function that does the same thing:

pF = Pick[#, UnitStep[#2 + #3 - #[[;; , 2]]], 1] &;

Examples:

min = RandomReal[{0, 0.5}, 10^6];
emin = RandomReal[{0, 0.5}, 10^6];
minimus = RandomReal[{0, 1}, {10^6, 2}];

p1 = pF[minimus, min, emin]; // AbsoluteTiming // First

0.059911

p2 = Pick[minimus, Thread[minimus[[;; , 2]] < (min + emin)]]; // 
  AbsoluteTiming // First

0.988790

p3 = First@Transpose@Select[Transpose@{minimus, min, emin}, 
     #[[1, 2]] < (#[[2]] + #[[3]]) &]; // AbsoluteTiming // First

2.497177

p1 == p2 == p3

True

Update: A variation suggested by @ciao in the comments is faster for large lists:

pFx = With[{tot = #2 + #3}, Pick[#, UnitStep[Subtract[tot, Transpose[#][[2]]]], 1]] &;

min = RandomReal[{0, 0.5}, 10^7];
emin = RandomReal[{0, 0.5}, 10^7];
minimus = RandomReal[{0, 1}, {10^7, 2}];

p1 = pF[minimus, min, emin]; // AbsoluteTiming // First

0.555083

p1x = pFx[minimus, min, emin]; // AbsoluteTiming // First

0.461842

p1x == p1

True

$\endgroup$
5
  • $\begingroup$ Amazing... I'm awesome to give the slowest solution! $\endgroup$
    – BlacKow
    Apr 19, 2016 at 17:24
  • $\begingroup$ We've both been schooled! $\endgroup$ Apr 19, 2016 at 17:32
  • $\begingroup$ @BlacKow and Quantum_Oli, thank you both for the votes. $\endgroup$
    – kglr
    Apr 19, 2016 at 17:54
  • 2
    $\begingroup$ I think you might find this a bit faster, particularly on large lists (at least it is on my machine): pFx=With[{tot = #2+ #3}, Pick[#, UnitStep[Subtract[tot, Transpose[#][[2]]]], 1]] &; - oh, and +1 o/c $\endgroup$
    – ciao
    Apr 20, 2016 at 0:53
  • $\begingroup$ @ciao, thank you so much. It is faster on my machine too. $\endgroup$
    – kglr
    Apr 20, 2016 at 1:13
4
$\begingroup$

Another approach, using Pick:

min = RandomReal[{0, 0.5}, 10]
emin = RandomReal[{0, 0.5}, 10]
minimus = RandomReal[{0, 1}, {10, 2}]

Pick[minimus, Thread[minimus[[;; , 2]] < (min + emin)]]
$\endgroup$
1
  • $\begingroup$ +1 Your approach is about twice faster than mine... $\endgroup$
    – BlacKow
    Apr 19, 2016 at 16:49
3
$\begingroup$

Assuming that you want to select all values from minimus such as its second element is less than sum of corresponding min and emin

RandomSeed[3141592];
minimus = RandomReal[{0, 1}, {10, 2}];
min = RandomReal[{0, 1}, 10];
emin = RandomReal[{0, 1}, 10];
First@Transpose@
  Select[Transpose@{minimus, min, 
     emin}, #[[1, 2]] < (#[[2]] + #[[3]]) &]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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