# Multiply a table with a sub-table of another table

Consider two grids of coordinates:

grid1 = Flatten[Table[{i, j}, {i, 1, 15}, {j, 1, 20}], 1]//N;
grid2 = Flatten[Table[{0.5 i, 0.5 j}, {i, 1, 45}, {j, 1, 60}], 1];


grid2 includes grid1 as a subset. In my realistic case, the pattern of the sub-set is more complicated than in this toy example.

Next, consider two tables:

tab1 = Join[grid1, {Exp[#[[1]]] Exp[-#[[2]]]} & /@ grid1, 2];
tab2 = Join[grid2, {Sin[#[[1]]] Tan[#[[2]]]} & /@ grid2, 2];


In my realistic case, they are pre-computed, I only know that tab2 is computed for grid2 and tab1 for grid1.

I want to multiply the elements of the third column of tab1 by the elements of the third column of tab2 for matching values of the first and the second column. I.e., the resulting table should be just tab1 but where the third column or the ith row is replaced by the multiplication of tab1[[i]][[3]]*tab2[[j]][[3]], with j belonging to the row of tab2 with the first and second columns coinciding with those of tab1[[i]]:

tab3=Join[grid1, {Sin[#[[1]]] Tan[#[[2]]] Exp[#[[1]]] Exp[-#[[2]]]} & /@ grid1, 2];


Could you please tell me how to obtain tab3 if having tab1, tab2 precomputed (so we cannot just use the expression above)?

• (a = (Most@# -> Last@#) & /@ tab1) // Short[#, 4] & (b = (Most@# -> Last@#) & /@ tab2) // Short[#, 4] & and Merge[KeyIntersection[{a, b}], Apply@Times] // Normal /. Rule[List[a_, b_], c_] :> {a, b, c}
– Syed
Apr 14 at 12:56
• (Merge[KeyIntersection[{a, b}], Apply@Times] // Normal) /. Rule[List[a_, b_], c_] :> {a, b, c} (missed opening parenthesis on comment above, going for a coffee break). Now you can focus on the speed part of it.
– Syed
Apr 14 at 13:04

KeyValueMap[
Append,
Merge[
KeyIntersection[{GroupBy[tab1, Most -> Last], GroupBy[tab2, Most -> Last]}],
Apply[Times]@*Flatten]]

• (+1) Do you know if there is such a thing as "ValueMap"? I mean, something that acts on the values of associations and not on the keys. Apr 14 at 18:56
• For most operations that work on lists, if you apply them to associations they automatically work on the values and not the keys. Apr 14 at 20:39
• So, ValueMap would just be Map. Apr 14 at 20:39
• Thanks for the clarification, @lericr! Apr 14 at 21:34

If you are sure that every element of grid1 is contained in grid2, then you could do it with Nearest as follows:

tab1[[All, 3]] *= tab2[[Flatten@ Nearest[tab2[[All, 1 ;; 2]] -> "Index", tab1[[All, 1 ;; 2]]], 3]];


Now tab1 should be equal to tab3.