Re: any better to apply a function to second column?

*To*: mathgroup at christensen.cybernetics.net*Subject*: [mg513] Re: [mg507] any better to apply a function to second column?*From*: villegas (Robert Villegas)*Date*: Mon, 6 Mar 1995 21:29:51 -0600

> I would like to know if there is a better way to > do the following. > > Suppose I have list of numbers in pairs: > > a = {{x1,y1},{x2,y2},...,{xn,yn}} > > I would like to apply to the sequence {y1,y2,...,yn} the function > f so that a new sequence > > b = {{x1,f[y1]},{x2,f[y2]},...,{xn,f[yn]}} > > is generated. Hello Richard, I think the shortest and clearest method is this: b = Apply[{#1, f[#2]}&, a, {1}]; > Also, what if I have a matrix of 3 or more columns and I would apply > f to only the second column, say. What is a better way in this case? The Apply method generalizes to an unknown number of additional columns like this: b = Apply[{#1, f[#2], ##3}&, a, {1}]; The ##3 stands for "the 3rd argument and beyond". For instance, if there were 6 columns, then ##3 would be a short way of representing the sequence (#3, #4, #5, #6). Examples: In[1]:= a = {{x1, y1}, {x2, y2}, {x3, y3}} Out[1]= {{x1, y1}, {x2, y2}, {x3, y3}} In[2]:= Apply[{#1, f[#2]}&, a, {1}] Out[2]= {{x1, f[y1]}, {x2, f[y2]}, {x3, f[y3]}} In[3]:= a = Table[{x[i], y[i], z[i], u[i], v[i], w[i]}, {i, 3}] Out[3]= {{x[1], y[1], z[1], u[1], v[1], w[1]}, > {x[2], y[2], z[2], u[2], v[2], w[2]}, > {x[3], y[3], z[3], u[3], v[3], w[3]}} In[4]:= Apply[{#1, f[#2], ##3}&, a, {1}] Out[4]= {{x[1], f[y[1]], z[1], u[1], v[1], w[1]}, > {x[2], f[y[2]], z[2], u[2], v[2], w[2]}, > {x[3], f[y[3]], z[3], u[3], v[3], w[3]}} See the Mathematica book entries on "Slot" and "SlotSequence" for more details. Another method similar to yours but which uses Transpose to extract the lists of abscissas and ordinates: b = {Transpose[a][[1]], f /@ Transpose[a][[2]]} //Transpose If the sublists are small (such as ordered pairs) and the number of sublists is large (such as ten thousand ordered pairs), then Transpose[matrix][[k]] is a faster way to extract the kth column than #[[k]]& /@ matrix. Here are a few other ways of doing it: Replace[#, {x_, y_} :> {x, f[y]}]& /@ a a /. {x_, y_} :> {x, f[y]} {#[[1]], f @ #[[2]]}& /@ a The second of these, using the "/." (ReplaceAll) operation, in general requires a little care because it searches all over the expression at all levels looking for things to replace, not just where you want it to. Hence, if the whole list 'a' had just two elements, the substitution rule would apply to the whole list, not to its sublists: In[9]:= {{x1, y1}, {x2, y2}} /. {x_, y_} :> {x, f[y]} Out[9]= {{x1, y1}, f[{x2, y2}]} If you know what 'a' is, then you can avoid this problem, but if 'a' is input by a user or generated programmatically, then you may not know how many elements 'a' has, so "/." could be unsafe. It's usually better to be direct. Robby Villegas