# I have the minimum Y value. I want to find the corresponding X value from the list [duplicate]

I have a very big file and contains data in the format of {x,y}. I got the minimum Y value by using

data[[All, 2]] // Min[#] &


Now I want to get the X value corresponding to the minimum Y value. How can I get it? Thanks a lot for your help ..!

• MinimalBy[data,Last] – BlacKow Jun 22 '15 at 20:31
• SortBy[data, Last] [[1, 1]] – MarcoB Jun 22 '15 at 20:33
• @MarcoB Wouldn't Sort take much more time in general case? – BlacKow Jun 22 '15 at 20:34
• //Min[#]& could be written shorter as //Min. – Sjoerd C. de Vries Jun 22 '15 at 21:09
• Related: (1342), (2177), (2434), (7679), (10143), (19300), (31385), (31878), (37594) – Mr.Wizard Jun 23 '15 at 10:25

One solution that is three to four times as fast as the fastest solution so far (halirutan's compiled Do loop) is:

data[[Ordering[data[[All, 2]], 1], 1]]


The obligatory timings:

MinimalBy[data, Last][[1, 1]] // RepeatedTiming
SortBy[data, Last][[1, 1]] // RepeatedTiming
SortBy[data, {Last}][[1, 1]] // RepeatedTiming
TakeSmallestBy[data, Last, 1][[1, 1]] // RepeatedTiming
minByLast[data] // RepeatedTiming
data[[Ordering[data[[All, 2]], 1], 1]] // RepeatedTiming


Output for random seed 5:

{2.0, 362.181}

{0.53, 362.181}

{0.49, 362.181}

{0.756, 362.181}

{0.12, 362.181}

{0.04, {362.181}}


Random seed 42:

{1.7, 375.714}

{0.50, 375.714}

{0.46, 375.714}

{0.78, 375.714}

{0.12, 375.714}

{0.032, {375.714}}


I note that even if you compile halirutan's code with CompilationTarget->"C" Ordering is still almost twice as fast.

• Ordering[#,1]  is probably treated as special case, because data[[Ordering[data[[All, 2]], 2], 1]] is almost 10 times slower... – BlacKow Jun 22 '15 at 21:40
• That was my first thought, but I dropped it without testing because we need to compare the last elements. My thought was that this makes it slower. It seems my decision was premature. +1 – halirutan Jun 22 '15 at 21:43
• @BlacKow Ordering[#,1] can be seen as the first stage in an unfinished sort. Ordering[#,2] is a successive stage, so necessarily must be slower. – Sjoerd C. de Vries Jun 22 '15 at 21:44
• @SjoerdC.deVries Is it documented anywhere what sorting algorithm is used? – BlacKow Jun 22 '15 at 21:48
• It should be something like data[[Ordering[data[[All, 2]], 1], 1]][[1]] or data[[Sequence @@ Ordering[data[[All, 2]], 1], 1]] to get the same output format (without the List) as the other methods. – Karsten 7. Jun 22 '15 at 22:06

As it seem a compiled stupid Do loop is a viable alternative and still the fastest on my machine:

minByLast = Compile[{{data, _Real, 2}},
Module[{min = First[data]},
Do[
If[Last[min] > Last[d], min = d], {d, data}];
First[min]
]
]


And in comparison with the methods proposed it still seems to win

SeedRandom[5]
data = RandomReal[1000, {2000000, 2}];

MinimalBy[data, Last][[1, 1]] // RepeatedTiming
SortBy[data, Last][[1, 1]] // RepeatedTiming
SortBy[data, {Last}][[1, 1]] // RepeatedTiming
TakeSmallestBy[data, Last, 1][[1, 1]] // RepeatedTiming
minByLast[data] // RepeatedTiming


• I can understand how your compiled version is the fastest. But how non-compiled SortBy is faster than non-compiled MinimalBy is beyond me... – BlacKow Jun 22 '15 at 21:14
• @BlacKow I think it is even worse with the new TakeSmallestBy function which should outperform all other solutions, because it is specifically made for, well, taking the smallest element from a list.. – halirutan Jun 22 '15 at 21:19
• Your minByLast is the fasted even when the time needed by Compile is included in the timing measurement. – Karsten 7. Jun 22 '15 at 21:21

@BlackKow raised an interesting point about speed of the two solutions we proposed in comments. Out of curiosity I timed the two solutions on a random data set:

SeedRandom[5]
data = RandomReal[1000, {2000000, 2}];

MinimalBy[data, Last] // RepeatedTiming
SortBy[data, Last][[1, 1]] // RepeatedTiming
SortBy[data, {Last}][[1, 1]] // RepeatedTiming

(* Out:
{1.68, {{362.181, 0.000374484}}}
{0.507, 362.181}
{0.473, 362.181}
*)


It seems that SortBy is still faster than MinimalBy. The stable sort version (third option) is slightly faster still, since it doesn't go into breaking ties after the sort-by-last has been completed.

• Whaaat? How this can be true? Care to share insights why? MinimalBy should take O(N)... – BlacKow Jun 22 '15 at 20:56
• TakeSmallestBy[data, Last, 1] – chuy Jun 22 '15 at 20:58
• @chuy I have to say it is embarrassing that a function like TakeSmallestBy, introduced in version 10.1 is twice as slow as a SortBy and 4x slower than a simple Do loop written in less than a minute. This makes such things nothing more then syntactic sugar. – halirutan Jun 22 '15 at 21:17
• @halirutan I can't disagree that it should be the fastest. – chuy Jun 22 '15 at 21:20

My two one candidate:

SeedRandom[5]
data = RandomReal[1000, {2000000, 2}];

(* First@Extract[data, Ordering[data[[All, 2]], 1]] // RepeatedTiming *) (* Sjoerd's *)
First@Nearest[#2 -> #1, Min[#2]] & @@ Transpose[data] // RepeatedTiming
(*

• Nearest was improved in V10.1. – Michael E2 Jun 23 '15 at 1:22
• No problem, and Nearest has become very fast indeed. In v9 the same code is almost 20 times slower. +1 – Sjoerd C. de Vries Jun 23 '15 at 9:46
• @Mr.Wizard Thanks. Nearest isn't as fast as Pick in the two closest questions, mathematica.stackexchange.com/q/10143 and mathematica.stackexchange.com/q/900. And, to my mind, Pick seems clearer. (I answered one question with this method, but just checked, and Pick is faster under certain conditions.) If you think I should add it to another question (of the two I mentioned, say), please suggest it and I will do it. – Michael E2 Jun 23 '15 at 22:48