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