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?
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
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP