4

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.

Patrick El Pollo
  • 593
  • 3
  • 12

4 Answers4

8
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}]
xyz
  • 605
  • 4
  • 38
  • 117
5

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

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
4
♯0 = # #[[;; , 1]] / #2 &;
♯0[lst1, lst2]

enter image description here

Alternatively,

Divide[lst1, lst2 ] lst1[[;;, 1]] 
lst1/lst2 lst1[[All, 1]]
(* same output *)
kglr
  • 394,356
  • 18
  • 477
  • 896
3

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]
P00pa
  • 31
  • 4