7
$\begingroup$

I have two 2D list

list1 = {{x,a1},{y,a2},{z,a3}}
list2 = {{x,b1},{y,b2},{z,b3}}

I want a list that divides only the second element of each element of the 2D array.

list3 = {{x,a1/b1},{y,a2/b2},{z,a3/b3}}

I know how to do this using a loop, but I want to know is there an elegant way using mathematica?

$\endgroup$
9
  • 3
    $\begingroup$ Some options: MapThread[{First[#1], Last[#1]/Last[#2]} &, {list1, list2}] or Thread[{list1[[All, 1]], list1[[All, 2]]/list2[[All, 2]]}] $\endgroup$ Mar 3, 2022 at 14:16
  • 1
    $\begingroup$ list1/{1, Last@#} & /@ list2 $\endgroup$
    – Syed
    Mar 3, 2022 at 14:16
  • 1
    $\begingroup$ list1/(ReplacePart[#, 1 -> 1] & /@ list2) $\endgroup$
    – Bob Hanlon
    Mar 3, 2022 at 14:19
  • $\begingroup$ @Syed - you are missing parentheses around denominator, i.e., list1/({1, Last@#} & /@ list2) $\endgroup$
    – Bob Hanlon
    Mar 3, 2022 at 14:20
  • $\begingroup$ Thanks @BobHanlon: It is always a good idea to have parentheses. Is it not evaluating on your machine, as I see this. $\endgroup$
    – Syed
    Mar 3, 2022 at 14:24

3 Answers 3

9
$\begingroup$
list3 = list1;
list3[[All, 2]] = list3[[All, 2]]/list2[[All, 2]];
list3
{{x, a1/b1}, {y, a2/b2}, {z, a3/b3}}

Also

list1 / Thread[{1, list2[[All, 2]]}]
{{x, a1/b1}, {y, a2/b2}, {z, a3/b3}}

and

SubsetMap[# / list2[[All, 2]]&, list1, {All, 2}]
{{x, a1/b1}, {y, a2/b2}, {z, a3/b3}}
$\endgroup$
2
$\begingroup$

A few more possibilities

a = {{x, a1}, {y, a2}, {z, a3}};

b = {{x, b1}, {y, b2}, {z, b3}};

Using SequenceCases with Riffle"

SequenceCases[Riffle[a, b], {a_, b_} :> {a[[1]], a[[2]] / b[[2]]}]

enter image description here

Using Cases with Transpose

Cases[Transpose[{a, b}], {a_, b_} :> {a[[1]], a[[2]] / b[[2]]}]

enter image description here

Using GroupBy

GroupBy[Join[a, b], First -> Last, Apply @ Divide]

enter image description here

Using Merge and MapApply (new in 13.1)

Merge[Apply @ Divide] @ MapApply[Rule] @ Join[a, b]

enter image description here

Association to List

KeyValueMap[List][%]

enter image description here

$\endgroup$
1
$\begingroup$
a = {{x, a1}, {y, a2}, {z, a3}};

b = {{x, b1}, {y, b2}, {z, b3}};

Using GatherBy and Replace at level 1:

rule = {{a__}, {b__}} :> {First@{a}, Divide @@ Last /@ {{a}, {b}}};

Replace[GatherBy[Join @@ {a, b}, First], rule, {1}]

{{x, a1/b1}, {y, a2/b2}, {z, a3/b3}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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