Example: suppose I want to divide entries in the 3rd column by 10.
(* my clunky solution *)
mat = ConstantArray[1, {10,5}];
res = Map[MapAt[#/10 &, #, 3] &, mat]
Note that the desired output is the entire matrix, so that rules out
something like:
mat[[All,3]]/10
One thing that would seem natural would be to allow "All" as an
element specification in the MapAt function. Thus, what I'm trying to
do would be expressed as:
(* doesn't work, but would be nice *)
MapAt[#/10 &, mat, {All,3}]
and if I wanted to do it to a specific row (say, the 3rd) it would be:
(* doesn't work, but would be nice *)
MapAt[#/10 &, mat, {3, All}]
Any thoughts/suggestions?
Thanks,
Peter.
> Hi,
> I'm wondering if there is a more simple/elegant way to Map a function
> to a specific row or column of a matrix. The best I can come up
> requires both Map and MapAt, but it feels like there should be
> something more succinct (I suspect I may be overlooking something
> obvious).
>
> Example: suppose I want to divide entries in the 3rd column by 10.
>
> (* my clunky solution *)
> mat = ConstantArray[1, {10,5}];
> res = Map[MapAt[#/10 &, #, 3] &, mat]
>
>
> Note that the desired output is the entire matrix, so that rules out
> something like:
>
> mat[[All,3]]/10
>
>
> One thing that would seem natural would be to allow "All" as an
> element specification in the MapAt function. Thus, what I'm trying to
> do would be expressed as:
>
> (* doesn't work, but would be nice *)
> MapAt[#/10 &, mat, {All,3}]
>
>
mat.DiagonalMatrix[{1, 1, 1/10, 1, 1}]
MapAt[#/10 &, mat, {#, 3} & /@ Range@Length@mat]
Transpose[MapAt[#/10 &, Transpose@mat, {3}]]
> and if I wanted to do it to a specific row (say, the 3rd) it would be:
>
> (* doesn't work, but would be nice *)
> MapAt[#/10 &, mat, {3, All}]
>
>
> MapAt[#/10 &, mat, {3}]
Adriano Pascoletti
Any thoughts/suggestions?
>
> Thanks,
> Peter.
>
>
Consider in-place modification, if you're working with a variable/
symbol:
mat = ConstantArray[1, {10,5}];
mat[[All,3]] /= 10;
or more generally:
mat[[All,3]] = op @ mat[[All, 3]];
where 'op' can of course be a function of more than its target.
Vince Virgilio
I would define my own function:
In[1] =
ClearAll[mapAt,MappedListable];
Protect[MappedListable];
Options[mapAt] = {MappedListable -> False};
mapAt[f_, expr_, {pseq : (All | _Integer) ..}, OptionsPattern[]] :=
Module[{copy = expr},
copy[[pseq]] =
If[TrueQ[OptionValue[MappedListable]] && Head[expr] === List,
f[copy[[pseq]]],
f /@ copy[[pseq]]
];
copy];
mapAt[f_, expr_, poslist_List] := MapAt[f, expr, poslist];
This will do what you want:
In[2] =
mat = ConstantArray[1, {10, 5}];
In[3] = mapAt[#/10 &, mat, {All, 3}]
Out[3] =
{{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1}}
In[4] = mapAt[#/10 &, mat, {3, All}]
Out[4] =
{{1,1,1,1,1},{1,1,1,1,1},{1/10,1/10,1/10,1/10,1/10},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1}}
Also, it can take advantage of listability of some built-in functions:
In[5] = largemat = ConstantArray[1, {50000, 5}];
In[6] = mapAt[#/10 &, largemat, {All, 3}]; // Timing
Out[6] = {0.062, Null}
In[7] = mapAt[#/10 &, largemat, {All, 3}, MappedListable -> True]; // Timing
Out[7] = {0.016, Null}
Regards,
Leonid
> Hi,
> I'm wondering if there is a more simple/elegant way to Map a function
> to a specific row or column of a matrix. The best I can come up
> requires both Map and MapAt, but it feels like there should be
> something more succinct (I suspect I may be overlooking something
> obvious).
>
> Example: suppose I want to divide entries in the 3rd column by 10.
>
> (* my clunky solution *)
> mat = ConstantArray[1, {10,5}];
> res = Map[MapAt[#/10 &, #, 3] &, mat]
>
>
> Note that the desired output is the entire matrix, so that rules out
> something like:
>
> mat[[All,3]]/10
>
>
> One thing that would seem natural would be to allow "All" as an
> element specification in the MapAt function. Thus, what I'm trying to
> do would be expressed as:
>
> (* doesn't work, but would be nice *)
> MapAt[#/10 &, mat, {All,3}]
>
> and if I wanted to do it to a specific row (say, the 3rd) it would be:
>
> (* doesn't work, but would be nice *)
> MapAt[#/10 &, mat, {3, All}]
>
>
> Any thoughts/suggestions?
I don't know if this is elegant, but you can specify all the
positions you want to operate on in a single MapAt expression:
operateOnColumn[mat_,col_,func_]:=MapAt[func,mat,{#,col}&/@Range[First
[Dimensions[mat]]]]
operateOnRow[mat_,row_,func_]:=MapAt[func,mat,{row,#}&/@Range[Last
[Dimensions[mat]]]]
Regards,
Ssezi
Good day,
A double transpose seems to be slightly faster than map+mapat :
In[1]:= mat=ConstantArray[1,{1000,500}];
In[2]:= res=Map[MapAt[#/10&,#,300]&,mat]//Timing//Short
Out[2]//Short= {0.047,{<<1>>}}
In[3]:= res=(tm=Transpose[mat];tm[[300]]/=10;tm//Transpose)//Timing//
Short
Out[3]//Short= {0.031,{<<1>>}}
--
V.Astanoff
Yep, there is. Double square brackets indicate coordinates.
To define a function as row x in a table defined as Table, for example, you'd write something like f=Table[[x]][All]]. I assume you can drop the same syntax into a mapping function.
------Original Message------
From: Vince
To: Mathgroup
Sent: Sep 3, 2009 7:56 PM
Subject: Re: Mapping to a specific column or row in a matrix
> Hi,
> obvious).
>
>
>
> something like:
>
> mat[[All,3]]/10
>
>
>
>
>
> Any thoughts/suggestions?
>
> Thanks,
> Peter.
Consider in-place modification, if you're working with a variable/
symbol:
mat = ConstantArray[1, {10,5}];
mat[[All,3]] /= 10;
MapAtLevel[f_, expr_, n_, levelspec_: {1}] :=
Map[MapAt[f, #, n] &, expr, levelspec - 1]
It looks like you did this, but called it clunky. By creating a new
function, it becomes much less clunky. I often have to plot data from
a list of {x,y} pairs, but I want to transform all the y values to
decibel:
dat = {{1, 200.}, {2, 250.}, {3, 300.}};
In[30]:= MapAtLevel[20 Log[10, #] &, dat, 2, 2]
Out[30]= {{1, 46.0206}, {2, 47.9588}, {3, 49.5424}}
Daniel
I'm not sure why this method works. Perhaps someone can clarify?
mat = ConstantArray[1, {10, 5}];;
mat[[All, 3]] = mat[[All, 3]]/10;
mat
In this method (which I use a lot), the rule depends on the structure
and its contents
mat = ConstantArray[1, {10, 5}];
mat = mat /. {a_, b_, x_Integer, c__} :> {a, b, x/10, c}
This method feels safe but I don't like it and it may be inefficient:
mat = ConstantArray[1, {10, 5}];
Do[mat = ReplacePart[mat, {k, 3} -> mat[[k, 3]]/10], {k, 1, 10}];
mat
John Jowett
On Sun, Sep 13, 2009 at 5:01 AM, John Jowett <john.m...@gmail.com>wrote:
> Here are a few other methods which work:
>
> I'm not sure why this method works. Perhaps someone can clarify?
>
> mat = ConstantArray[1, {10, 5}];;
> mat[[All, 3]] = mat[[All, 3]]/10;
> mat
>
>
Your code uses the special case of the extended functionality of Part, which
Vince and myself also used (somewhat more generally) in our posts earlier in
this thread. It works because <mat> is an L-value (can be modified
in-place), and because Part has this extended functionality to make multiple
assignments to regular (sub)structures simultaneously. The side effect of
execution of your code is that <mat> is modified. If this is not desirable,
one can use a local variable (like I did In my version),
Regards,
Leonid
> In this method (which I use a lot), the rule depends on the structure
> and its contents
>
> mat = ConstantArray[1, {10, 5}];
> mat = mat /. {a_, b_, x_Integer, c__} :> {a, b, x/10, c}
>
>
> This method feels safe but I don't like it and it may be inefficient:
>
> mat = ConstantArray[1, {10, 5}];
> Do[mat = ReplacePart[mat, {k, 3} -> mat[[k, 3]]/10], {k, 1, 10}];
> mat
>
> John Jowett
>
>
>
> On Sep 10, 1:16 pm, dr DanW <dmaxwar...@gmail.com> wrote: