4
$\begingroup$

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.

$\endgroup$
1
  • 2
    $\begingroup$ Transpose[{list1[[All, 1]], Times @@@ list2/list1[[All, 2]]}] $\endgroup$
    – ciao
    May 16 '15 at 1:03
8
$\begingroup$
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}]
$\endgroup$
1
  • 1
    $\begingroup$ You can also use MapThread[{First@#1, Times @@ #1 /Last@#2} &, {lst1, lst2}] $\endgroup$
    – ubpdqn
    May 16 '15 at 1:41
5
$\begingroup$

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
$\endgroup$
1
  • $\begingroup$ I always like your and @kguler 's answer, because I learned much from you:-) $\endgroup$
    – xyz
    May 16 '15 at 13:08
4
$\begingroup$
♯0 = # #[[;; , 1]] / #2 &;
♯0[lst1, lst2]

enter image description here

Alternatively,

Divide[lst1, lst2 ] lst1[[;;, 1]] 
lst1/lst2 lst1[[All, 1]]
(* same output *)
$\endgroup$
3
$\begingroup$

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]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.