MathGroup Archive 1995

[Date Index] [Thread Index] [Author Index]

Search the Archive

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

>    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).


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

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

  • Prev by Date: Re: Numerical evaluation of HypergeometricPFQ[{a,b,c},{d,e},1]
  • Next by Date: RE: BarCharts and vertical axes
  • Previous by thread: any better to apply a function to second column?
  • Next by thread: Re: any better to apply a function to second column?