TransWikia.com

Map and Apply a function on a nested list

Mathematica Asked by Eiyrioü von Kauyf on May 1, 2021

I have a list like this:

{{1,2}, {4,2}, {6,4} ... }

I want to replace every second number with a function of that number. For e.g.

{{1, Log[2]}, {4,Log[2]}, {6,Log[4]} ...}

It is ok if the actual number is evaluated e.g. {1, .301} for the first one. I am trying to do this with a combination of Apply, Map and ReplacePart but am having no luck.

I do not understand how to do @@ in cases where the nested list is supplied as an argument to the function.

10 Answers

You can define a function as :

myF[alist_, f_] := Map[{#[[1]], f[#[[2]]]} &, alist]

myF[{{1, 2}, {4, 2}, {6, 4}}, Log]

(* {{1, Log[2]}, {4, Log[2]}, {6, Log[4]}} *)

Or you can generalize to :

myF2[alist_, f_] := Map[{f[[1]][#[[1]]], f[[2]][#[[2]]]} &, alist]

myF2[alist, {# &, Log}]
myF2[alist, {Sin, Log}]

(* {{1, Log[2]}, {4, Log[2]}, {6, Log[4]}} *)
(* {{Sin[1], Log[2]}, {Sin[4], Log[2]}, {Sin[6], Log[4]}} *)

Correct answer by b.gates.you.know.what on May 1, 2021

You can use ReplaceAll i.e.

{{1, 2}, {4, 2}, {6, 4}} /. {a_, b_} -> {a, Log[b]}
{{1, Log[2]}, {4, Log[2]}, {6, Log[4]}}

or

{#1, Log[#2]} & @@@ {{1, 2}, {4, 2}, {6, 4}}

i.e. Apply the function {#1, Log[#2]} & on the first level of the expression.

Answered by Artes on May 1, 2021

My explanation of # &, #2 &, ## &, ##2 & can be found in my Mathematica tips and tricks pages as part of the section discussing Function.

Answered by Ted Ersek on May 1, 2021

Since you seem to be relatively new to Mathematica, and unfamiliar with all its special syntax (/@, @@@ etc), I would normally recommend Artes' second answer:

{#1, Log[#2]} & @@@ {{1, 2}, {4, 2}, {6, 4}}

Which can also be written

Apply[{#1, Log[#2]} &, testdata, {1}]

where testdata = {{1, 2}, {4, 2}, {6, 4}}

Some alternative ways of getting the same answer include:

MapThread[{#1, Log[#2]} &, Transpose@testdata]

and (I think this one is quite cool)

Inner[#1[#2] &, {# &, Log[#] &}, Transpose@testdata, List]

Answered by Verbeia on May 1, 2021

MapAt and deeply nested lists generalization

Another way to do this:

MapAt[Log, #, 2] & /@ {{1,2}, {4,2}, {6,4}}

{{1, Log[2]}, {4, Log[2]}, {6, Log[4]}}

Which is useful if we target a specific element inside every element of a deeply nested list:

data = Table[{k, {k, {{k}}}}, {k, 2, 5}]

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

MapAt[Log, #, {2, 2}] & /@ data

{{2,{2,{{Log[2]}}}}, {3,{3,{{Log[3]}}}}, {4,{4,{{Log[4]}}}}, {5,{5,{{Log[5]}}}}}

Answered by Vitaliy Kaurov on May 1, 2021

when f is listable, use Set and Part:

a = {{1, 2}, {4, 2}, {6, 4}};
a[[All, 2]] = Log@a[[All, 2]];
a

Answered by kptnw on May 1, 2021

From my answer in the thread that Leonid linked:

partReplace[dat_, func_, spec__] :=
  Module[{a = dat},
    a[[spec]] = func @ a[[spec]];
    a
  ]

partReplace[{{1, 2}, {4, 2}, {6, 4}}, Log, All, 2]
{{1, Log[2]}, {4, Log[2]}, {6, Log[4]}}

Though this fails on version 7, ruebenko's answer is IMHO the most elegant for recent versions:

partReplace2[dat_, func_, spec__] := ReplacePart[data, {spec} -> func @ data[[spec]] ]

These both assume that func is Listable.

Answered by Mr.Wizard on May 1, 2021

Here's a variation of b.gatessucks's generalization:

Map[Composition[Through, {Composition[f1, First], Composition[f2, Last]}],
    {{1, 2}, {4, 2}, {6, 4}}]
   {{f1[1], f2[2]}, {f1[4], f2[2]}, {f1[6], f2[4]}}

For OP's particular example:

Map[Composition[Through, {Composition[Identity, First], Composition[Log, Last]}],
    {{1, 2}, {4, 2}, {6, 4}}]
   {{1, Log[2]}, {4, Log[2]}, {6, Log[4]}}

Answered by J. M.'s ennui on May 1, 2021

MapAt was updated some versions ago (V10? but not documented until V11.1) to handle this use-case. An example similar to this may be found in the documentation:

MapAt[Log, {{1, 2}, {4, 2}, {6, 4}}, {All, 2}]
(*  {{1, Log[2]}, {4, Log[2]}, {6, Log[4]}}  *)

Answered by Michael E2 on May 1, 2021

Be careful, some method is really slow. :) The fastest one is always the "vectorization one".

enter image description here

Answered by Nam Nguyen on May 1, 2021

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