3
$\begingroup$

I have a long table with the form {{a1,b1,c1}, ... , {an,bn,cn}}; how do I extract the values of a and b corresponding to the maximum value of c?

$\endgroup$
  • 7
    $\begingroup$ MaximalBy[list, Last]? $\endgroup$ – march Dec 28 '17 at 20:43
5
$\begingroup$

Also

TakeLargestBy[list, Last,1],
list[[Ordering[list[[All, -1]], -1][[1]]]]
$\endgroup$
4
$\begingroup$

A comparison of the proposed methods (I stored the Max for the two last cases to avoid multiple computations).

SeedRandom[1]
tab[n_] := RandomReal[10, {n, 3}];

compare[n_] := With[{tab = tab[n]}, {
    RepeatedTiming@MaximalBy[tab, Last]
    , RepeatedTiming@TakeLargestBy[tab, Last, 1]
    , RepeatedTiming[tab[[Ordering[tab[[All, -1]], -1][[1]]]]]
    , RepeatedTiming[max = Max[tab[[All, 3]]]; Select[tab, #[[3]] == max &]]
    , RepeatedTiming[max = Max[tab[[All, 3]]]; Pick[tab, #[[3]] == max & /@ tab]]
    , RepeatedTiming[Pick[list, Unitize@Clip[
         list[[All, 3]], {Max[list[[All, 3]]], Max[list[[All, 3]]]}, {0,   0}], 1]]
    }[[All, 1]]]

res = Table[compare[Floor[10^n]], {n, 1, 6, 0.25}];
ListLinePlot[Transpose@res, DataRange -> {0, 10^6}, 
   PlotLegends -> {"MaximalBy", "TakeLargestBy", "Ordering", "Select", 
       "Pick", "Pick & Clip"}]

enter image description here

The Ordering method proposed by klgr is the fastest by far here. Second is the combination of Pick and Clip proposed by mrz (and earlier in this post by Carl Woll).

$\endgroup$
  • $\begingroup$ Please update you overview with the Pick and Clip solution (my lowest solution) which is slightly slower (on my computer) than Ordering. $\endgroup$ – mrz Dec 29 '17 at 16:36
  • $\begingroup$ @mrz Done. Don't hesitate to improve answers directly yourself. $\endgroup$ – anderstood Dec 29 '17 at 19:01
3
$\begingroup$
SeedRandom[1];

list = RandomReal[10, {10, 3}]

{{8.17389, 1.1142, 7.89526}, {1.87803, 2.41361, 0.657388}, 
 {5.42247, 2.31155, 3.96006}, {7.00474, 2.11826, 7.48657}, 
 {4.22851, 2.47495, 9.77172}, {8.25163, 9.25275, 5.78056}, 
 {2.9287, 2.08051, 5.80474}, {1.28821, 3.06427, 7.12012}, 
 {3.90582, 8.19967, 3.25351}, {5.9326, 5.18774, 1.69013}}

Select[list, #[[3]] == Max[list[[All, 3]]] &]

{{4.22851, 2.47495, 9.77172}}

Pick[list, #[[3]] == Max[list[[All, 3]]] & /@ list]

{{4.22851, 2.47495, 9.77172}}

Pick[
  list, 
  Unitize@Clip[
    list[[All, 3]], {Max[list[[All, 3]]], Max[list[[All, 3]]]}, {0, 0}
  ], 1
]

{{4.22851, 2.47495, 9.77172}}
$\endgroup$
1
$\begingroup$

If performance is an issue, Pick gives a very fast answer:

Pick[list,list[[All,3]],Max[list[[All,3]]] ]  
$\endgroup$
  • $\begingroup$ Yes, thank you ! $\endgroup$ – Ulrich Neumann Dec 29 '17 at 11:10

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.