4
$\begingroup$

Consider two tables:

tab1=Flatten[Table[{i,j,0},{i,0.5,0.7,0.1},{j,0.1,0.3,0.1}],{1,2}];
tab2=Flatten[Table[{i,j,i*j},{i,0.5,0.7,0.2},{j,0.1,0.3,0.2}],{1,2}];

These tables have a common subset of the first and second elements of their rows: e.g., {0.5,0.1}, and {0.7,0.3}. How to make a table from tab1 where zeros (the third element) in the rows from the common subset are replaced with the corresponding values from tab2?

$\endgroup$

7 Answers 7

6
$\begingroup$

Something along these lines might work:

tab2Rules = Thread[ReplacePart[3 -> _] /@ tab2 -> tab2];
tab1 /. tab2Rules

{{0.5, 0.1, 0.05}, {0.5, 0.2, 0}, {0.5, 0.3, 0.15}, {0.6, 0.1, 0}, {0.6, 0.2, 0}, {0.6, 0.3, 0}, {0.7, 0.1, 0.07}, {0.7, 0.2, 0}, {0.7, 0.3, 0.21}}

$\endgroup$
5
$\begingroup$
Clear["Global`*"]
tab1 = Flatten[
   Table[{i, j, 0}, {i, 0.5, 0.7, 0.1}, {j, 0.1, 0.3, 0.1}], {1, 2}];
tab2 = Flatten[
   Table[{i, j, i*j}, {i, 0.5, 0.7, 0.2}, {j, 0.1, 0.3, 0.2}], {1, 
    2}];

Create rules for a Lookup:

r1 = Sequence @@@ ({Most@# -> Last@#} & /@ tab2)

{{0.5, 0.1} -> 0.05, {0.5, 0.3} -> 0.15, {0.7, 0.1} -> 0.07, {0.7, 0.3} -> 0.21}

Sequence @@@ {Most@#, Lookup[r1, {Most@#}, Last@#]} & /@ tab1 

{{0.5, 0.1, 0.05}, {0.5, 0.2, 0}, {0.5, 0.3, 0.15}, {0.6, 0.1, 0}, {0.6, 0.2, 0}, {0.6, 0.3, 0}, {0.7, 0.1, 0.07}, {0.7, 0.2, 0}, {0.7, 0.3, 0.21}}

$\endgroup$
3
$\begingroup$

Using Association - overwriting

Join @@ Values @ Association[GroupBy[Most] @ tab1, GroupBy[Most] @ tab2]

{{0.5, 0.1, 0.05}, {0.5, 0.2, 0}, {0.5, 0.3, 0.15}, {0.6, 0.1, 0}, {0.6, 0.2, 0}, {0.6, 0.3, 0}, {0.7, 0.1, 0.07}, {0.7, 0.2, 0}, {0.7, 0.3, 0.21}}

$\endgroup$
3
$\begingroup$
Replace[tab1,(MapThread[{#1,#2,0}->{##1}&,Transpose@tab2]),2]

(* {
    {0.5,0.1,0.05},
    {0.5,0.2,0},
    {0.5,0.3,0.15},
    {0.6,0.1,0},
    {0.6,0.2,0},
    {0.6,0.3,0},
    {0.7,0.1,0.07},
    {0.7,0.2,0},
    {0.7,0.3,0.21}
   } *)
$\endgroup$
3
$\begingroup$

Using Merge and MapApply (new in 13.1)

res = Merge[Last] @ MapApply[{#1, #2} -> #3 &] @ Join[tab1, tab2]

<|{0.5, 0.1} -> 0.05, {0.5, 0.2} -> 0, {0.5, 0.3} -> 0.15, {0.6, 0.1} -> 0, {0.6, 0.2} -> 0, {0.6, 0.3} -> 0, {0.7, 0.1} -> 0.07, {0.7, 0.2} -> 0, {0.7, 0.3} -> 0.21|>

Convert to lists

KeyValueMap[Flatten @* List] @ res

{{0.5, 0.1, 0.05}, {0.5, 0.2, 0}, {0.5, 0.3, 0.15}, {0.6, 0.1, 0}, {0.6, 0.2, 0}, {0.6, 0.3, 0}, {0.7, 0.1, 0.07}, {0.7, 0.2, 0}, {0.7, 0.3, 0.21}}

$\endgroup$
2
$\begingroup$

My attempt to do this, defining ReplaceByCoords:

 ReplaceByCoords[tab1_, tab2_] := 
 Module[{assis, res}, 
 assis[elem_] := 
 Module[{match}, match = SelectFirst[tab2, Most[#] == Most[elem] &];
 If[MissingQ[match], elem, match]]; es = assis /@ tab1; res]

Testing ReplaceByCoords:

res = {{0.5, 0.1, 0.05}, {0.5, 0.2, 0}, {0.5, 0.3, 0.15}, {0.6, 0.1, 0}, 
      {0.6, 0.2, 0}, {0.6, 0.3, 0}, {0.7, 0.1, 0.07}, {0.7, 0.2, 0}, 
      {0.7, 0.3, 0.21}};

ReplaceByCoords[tab1, tab2] === res

(*True*)
$\endgroup$
2
$\begingroup$
Values @ AssociationThread[Most /@ #, #] & @ Join[tab1, tab2]
{{0.5, 0.1, 0.05}, {0.5, 0.2, 0}, {0.5, 0.3, 0.15}, {0.6, 0.1, 0},   
 {0.6, 0.2, 0}, {0.6, 0.3, 0}, {0.7, 0.1, 0.07},   
 {0.7, 0.2, 0}, {0.7, 0.3, 0.21}}

Replacements highlighted:

% /. a : Alternatives @@ tab2 :> Highlighted[a] 

enter image description here

$\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.