4
$\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$
1
  • 7
    $\begingroup$ MaximalBy[list, Last]? $\endgroup$
    – march
    Commented Dec 28, 2017 at 20:43

4 Answers 4

6
$\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$
2
  • $\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
    Commented Dec 29, 2017 at 16:36
  • $\begingroup$ @mrz Done. Don't hesitate to improve answers directly yourself. $\endgroup$
    – anderstood
    Commented Dec 29, 2017 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$
2
$\begingroup$

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

Pick[list,list[[All,3]],Max[list[[All,3]]] ]  
$\endgroup$
1
  • $\begingroup$ Yes, thank you ! $\endgroup$ Commented Dec 29, 2017 at 11:10

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.