# How to multiply lists of data?

Let two lists of data, say

lst1={{x1,y1},{x2,y2},...,{xn,yn}}

lst2={{x1,z1},{x2,z2},...,{xn,zn}}


I need to construct a third list

lst3={{x1,x1*z1/y1},{x2,x2*z2/y2},...,{xn,xn*zn/yn}}


Look, this is an operation involving the y-elements of each list and also the x-element.

• Transpose[{list1[[All, 1]], Times @@@ list2/list1[[All, 2]]}]
– ciao
May 16, 2015 at 1:03

lst1 = {{x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}};
lst2 = {{x1, z1}, {x2, z2}, {x3, z3}, {x4, z4}};

{#1, #1 #4/#2} & @@@ (Flatten[#, 1] & /@ Thread@{lst1, lst2})


$\left\{\left\{\text{x1},\frac{\text{x1} \text{z1}}{\text{y1}}\right\},\left\{\text{x2},\frac{\text{x2} \text{z2}}{\text{y2}}\right\},\left\{\text{x3},\frac{\text{x3} \text{z3}}{\text{y3}}\right\},\left\{\text{x4},\frac{\text{x4} \text{z4}}{\text{y4}}\right\}\right\}$

Or

{#1, #1 #4/#2} & @@@ (Flatten[#, 1] & /@ Transpose[{lst1, lst2}])


Or

Flatten[#, 1] & /@ Transpose[{lst1, lst2}] /.
{x_, y_, x_, z_} :> {x, x z/y}

Flatten[#, 1] & /@ Thread@{lst1, lst2})/.
{x_, y_, x_, z_} :> {x, x z/y}


As mentioned by @ubpdqn in the comment, you can also using

MapThread[{First@#1, Times @@ #1/Last@#2} &, {lst1, lst2}]

• You can also use MapThread[{First@#1, Times @@ #1 /Last@#2} &, {lst1, lst2}] May 16, 2015 at 1:41

Join is quite clean I think:

lst1 = {{x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}};
lst2 = {{x1, z1}, {x2, z2}, {x3, z3}, {x4, z4}};

{#, #*#4/#2} & @@@ Join[lst1, lst2, 2]

{{x1, (x1 z1)/y1}, {x2, (x2 z2)/y2}, {x3, (x3 z3)/y3}, {x4, (x4 z4)/y4}}


For more efficiency a Transpose pair lets one operate by column enabling vector arithmetic on packed arrays:

{#, #*#4/#2}\[Transpose] & @@ (Join[lst1, lst2, 2]\[Transpose])


{{x1, (x1 z1)/y1}, {x2, (x2 z2)/y2}, {x3, (x3 z3)/y3}, {x4, (x4 z4)/y4}}

Timings with a large array of reals:

{lst1, lst2} = List @@ RandomReal[{1, 99}, {2, 500000, 2}];

{#, #*#4/#2} & @@@ Join[lst1, lst2, 2] // Timing // First
{#, #*#4/#2}\[Transpose] & @@ (Join[lst1, lst2, 2]\[Transpose]) // Timing // First

0.763

0.025


Shutao Tang's methods for comparison:

{#1, #1 #4/#2} & @@@ (Flatten[#, 1] & /@ Thread@{lst1, lst2}) // Timing // First

{#1, #1 #4/#2} & @@@ (Flatten[#, 1] & /@ Transpose[{lst1, lst2}]) //
Timing // First

Flatten[#, 1] & /@ Transpose[{lst1, lst2}] /. {x_, y_, x_, z_} :> {x, x z/y} //
Timing // First

Flatten[#, 1] & /@ Thread@{lst1, lst2} /. {x_, y_, x_, z_} :> {x, x z/y} //
Timing // First

MapThread[{First@#1, Times @@ #1/Last@#2} &, {lst1, lst2}] // Timing // First

1.13

0.831

0.687

0.982

1.42

• I always like your and @kguler 's answer, because I learned much from you:-)
– xyz
May 16, 2015 at 13:08
♯0 = # #[[;; , 1]] / #2 &;
♯0[lst1, lst2] Alternatively,

Divide[lst1, lst2 ] lst1[[;;, 1]]
lst1/lst2 lst1[[All, 1]]
(* same output *)


Using MapIndexed

 lst1 = {{x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}};
lst2 = {{x1, z1}, {x2, z2}, {x3, z3}, {x4, z4}};

MapIndexed[{First@#1,(First@#1/Last@#1)*lst2[[Last@#2,2]]}&,lst1]