5
$\begingroup$

I have a list as follows

lis1={{{1,5,6},{4,7,8}},{{1,2,2},{5,6,7}}}

and would like to calculate the max value of each nested list in order to get following result

lis2={{6,8},{2,7}}

Does anyone have a hint. Thanks

$\endgroup$
1
  • 3
    $\begingroup$ you can use Map[Max,list,level] $\endgroup$ Commented Apr 28, 2015 at 19:56

5 Answers 5

10
$\begingroup$
Apply[Max, lis1, {2}]
(*  {8, 7}  *)

If the list has varying depths, then

lis1 /. v_?VectorQ :> Max[v]
(* {{6, 8}, {2, 7}}  *)

For example

{{{1, 5, 6}, {{{4, 7, 8}}}}, {{{1, 2, 2}}, {5, 6, 7}}} /.  v_?VectorQ :> Max[v]
(*  {{6, {{8}}}, {{2}, 7}}  *)

If lis1 is a large packed array, then ReplaceAll, Apply and Map will unpack it. In that case one can compile Map:

On["Packing"];
Compile[{{x, _Integer, 3}}, Map[Max, x, {2}]] @
 RandomInteger[100, {10, 2, 3}]
Off["Packing"];
(*
  {{90, 45}, {90, 82}, {81, 77}, {72, 96}, {87, 35},
   {72, 97}, {74, 61}, {56, 69}, {78, 99}, {77, 92}}
*)

Or packaged in a function:

paMax[a_?Developer`PackedArrayQ] := With[{level = ArrayDepth[a]},
  Compile[{{x, _Integer, level}}, Map[Max, x, {-2}]][a]]

paMax[RandomInteger[100, {10, 2, 3}]]
(*
  {{70, 85}, {93, 81}, {49, 20}, {80, 86}, {98, 80},
   {86, 69}, {47, 98}, {82, 88}, {77, 66}, {93, 88}}
*)
$\endgroup$
2
  • $\begingroup$ It is my first time to see the usage of On["Packing"];Off["Packing"];. Then I search the Documentation, but I didn't discover the information about it. So could you give me some ditails about it? Thanks sincerely:) $\endgroup$
    – xyz
    Commented Apr 29, 2015 at 9:12
  • $\begingroup$ @ShutaoTang It's described briefly in the docs for On. They turn on and off the group of messages that warns the user when a packed array is unpacked. (It does not help the code run better.) $\endgroup$
    – Michael E2
    Commented Apr 29, 2015 at 10:02
4
$\begingroup$
Max @@@ # & /@ lis1
(* {{6, 8}, {2, 7}} *)
$\endgroup$
2
$\begingroup$

How about

Max@# & /@ lis1[[#]] & /@ Range@Length@lis1

or, as Belisarius said,

Map[Max, lis1, #] & /@ Range@Length@lis1

or, for something like

lis1 = {{1, 2, 3}, {{{{{25, 5, 4}}}}}, {{{4, 5, 6}}}, {{5, 10, 7}}};

you can use

Replace[lis1, x__ :> Max@x, 1]

(*{3, 25, 6, 10}*)
$\endgroup$
2
$\begingroup$
list = {{{1, 5, 6}, {4, 7, 8}}, {{1, 2, 2}, {5, 6, 7}}};

1.

With ArrayReduce (new in 12.2)

ArrayReduce[Max, list, 3]

{{6, 8}, {2, 7}}

Developer`PackedArrayQ[%]

True

2.

With AggregationLayer (new in 11.1)

Round @ AggregationLayer[Max, 3] @ list

{{6, 8}, {2, 7}}

Developer`PackedArrayQ[%]

True

$\endgroup$
2
$\begingroup$

Using GroupBy and Max:

lis1 = {{{1, 5, 6}, {4, 7, 8}}, {{1, 2, 2}, {5, 6, 7}}};

Keys@GroupBy[lis1, Max /@ # &]

(*{{6, 8}, {2, 7}}*)
$\endgroup$

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.