MapThread[Max, {{2, 3, 5, 4, 1, 8, 7} , {1, 4, 6, 3, 2, 8, 8}}]
{2, 4, 6, 4, 2, 8, 8}
Thread[Unevaluated[Max[{2, 3, 5, 4, 1, 8, 7} , {1, 4, 6, 3, 2, 8, 8}]]]
also works. Unevaluated
is necessary, otherwise Max[...
evaluates, before Thread
acts on it. On the other hand
Thread[Unevaluated[Max[list1, list2]]]
does not work for the same reasons.
list1 = RandomInteger[30, 1*^7];
list2 = RandomInteger[30, 1*^7];
MapThread[Max, {list1, list2}] // AbsoluteTiming
{6.302683, {28, 10, 21, 13 ...
Not too bad for ten million elements. In fact, faster than constructing the lists.
In this simple case however, we can do 10 times better:
(Max /@ Transpose@{list1, list2}) // AbsoluteTiming // First
0.608412
For a list with 2 dimensions the obvious solution is
MapThread[Max, {list1, list2}, 2] // AbsoluteTiming // First
0.702000
Timing is shown for a 10^3
by 10^3
list.
The faster solution uses the, so-to-speak, generalized transpose, which is achieved by using flatten with a matrix as the second argument:
Map[Max, Flatten[{list1, list2}, {{2}, {3}, {1}}], {2}] // AbsoluteTiming // First
0.109200
As before, almost an order of magnitude faster. The general expression for k
-dimensional lists would be:
Map[Max, Flatten[{list1, list2}, {{2}, {3}, ..., {k+1}, {1}}], {k}]
Update 18.09.17
Carl Woll's ThreadedMax
is hard to beat, but exploiting Compile
d listability comes close:
threadMax =
Compile[{{x1, _Integer}, {x2, _Integer}}, Max[x1, x2],
RuntimeAttributes -> {Listable}, Parallelization -> True,
CompilationTarget -> "C", RuntimeOptions -> "Speed"]
It is still a few times slower though and I'd recommend Carl's solution. Simple top-level functions with built-in listability are close to impossible to beat even with compiled functions and are more versatile in the datatypes they accept: e.g., the above threadMax
will only work on packed arrays of integers.
If Ramp
isn't available in your version of MMA, just like it is in mine (I'm on 10.2), I suggest the following implementation:
ThreadedMax[l1_List, l2_List] :=
With[{diff = Subtract[l1, l2]},
Check[UnitStep[diff] diff + l2, $Failed]]
I would similarly modify Carl's solution like so for better performance:
ThreadedMax[l1_List, l2_List] := Check[
Ramp[Subtract[l1, l2]]+l2,
$Failed
]
See this for further reading.