TransWikia.com

Finding the maximum from a two dimensional list

Mathematica Asked by D.Nanda on December 4, 2020

I have a two-dimensional list where each value of $ x $ can have many values of $ y $. for example

{{1, 2}, {1, 3}, {1, 4}, {2, 2}, {2, 3}, {2, 4}, {2, 5}}

For each value of $ x $, I have to find out the maximum value of $ y $. So, the result will be like

{{1, 4}, {2, 5}}

I tried with Max, Short but was not able to run this in the loop.

Is there an efficient method?

6 Answers

Using GroupBy and MaximalBy

gpLst = GroupBy[lst, First, MaximalBy[#, Last][[1]] &]

<|1 -> {{1, 4}}, 2 -> {{2, 5}}|>

gpLst//Values

{{1, 4}, {2, 5}}

Correct answer by Anjan Kumar on December 4, 2020

Since you specified "Is there an efficient method?"

GatherBy[Sort@list, First][[All, -1]]

(here list is your list or variable the list is assigned to).

This should outperform the accepted solution by at least an order of magnitude.

Slightly more verbose, but even quicker:

With[{g = GatherBy[list, First]}, 
 Transpose[{g[[All, 1, 1]], Max /@ g[[All, All, 2]]}]]

Answered by ciao on December 4, 2020

list = {{1, 2}, {1, 3}, {1, 4}, {2, 2}, {2, 3}, {2, 4}, {2, 5}};
MaximalBy[#, Last] & /@ Split[list, #1[[1]] == #2[[1]] &]

Answered by A little mouse on the pampas on December 4, 2020

Another one:

data = {{1, 2}, {1, 3}, {1, 4}, {2, 2}, {2, 3}, {2, 4}, {2, 5}};
GroupBy[data, First -> Last, Max]

<|1 -> 4, 2 -> 5|>

If you need the result as a list of pairs:

KeyValueMap[List, %]

{{1, 4}, {2, 5}}

Answered by Sjoerd Smit on December 4, 2020

Here's a variation of @sjoerd's answer:

data={{1,2},{1,3},{1,4},{2,2},{2,3},{2,4},{2,5}};

ResourceFunction["GroupByList"][data[[All,2]],data[[All,1]],Max]

<|1 -> 4, 2 -> 5|>

For large datasets, this will be much faster than GroupBy:

data = RandomInteger[10000, {10^6, 2}];
r1=ResourceFunction["GroupByList"][data[[All,2]], data[[All,1]], Max];//AbsoluteTiming
r2=GroupBy[data, First->Last, Max];//AbsoluteTiming

r1===r2

{0.10384, Null}

{0.514609, Null}

True

This approach is also slightly faster than @ciao's.

Answered by Carl Woll on December 4, 2020

Similar in spirit to Sjoerd Smit's answer: the wonderful thing about Mathematica's associations is that they automatically override earlier values in favor of later ones, which is exactly what you want! To demonstrate, let me shuffle your input:

data = {{1, 2}, {1, 4}, {2, 2}, {2, 4}, {2, 5}, {1, 3}, {2, 3}}

Converting into an association only keeps the last occurrence of each first coordinate:

AssociationThread @@ Transpose@data

returns <|1 -> 3, 2 -> 3|>. So we just need to sort first (fortunately Sort automatically checks second coordinates after it checks first coordinates):

AssociationThread @@ Transpose@Sort@data

returns <|1 -> 4, 2 -> 5|>. And if you want the answer as ordered pairs again, there's a function that does that:

KeyValueMap[List, AssociationThread @@ Transpose@Sort@data]

returns {{1, 4}, {2, 5}}.

Answered by Greg Martin on December 4, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP