4

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?

anderstood
  • 14,301
  • 2
  • 29
  • 80
mattiav27
  • 6,677
  • 3
  • 28
  • 64

4 Answers4

6

Also

TakeLargestBy[list, Last,1],
list[[Ordering[list[[All, -1]], -1][[1]]]]
kglr
  • 394,356
  • 18
  • 477
  • 896
4

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).

anderstood
  • 14,301
  • 2
  • 29
  • 80
  • Please update you overview with the Pick and Clip solution (my lowest solution) which is slightly slower (on my computer) than Ordering. – mrz Dec 29 '17 at 16:36
  • @mrz Done. Don't hesitate to improve answers directly yourself. – anderstood Dec 29 '17 at 19:01
3
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}}
mrz
  • 11,686
  • 2
  • 25
  • 81
2

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

Pick[list,list[[All,3]],Max[list[[All,3]]] ]  
Ulrich Neumann
  • 53,729
  • 2
  • 23
  • 55