7
$\begingroup$

Consider the following tables:

ival = 10^6;
Tab1 = Table[{x, y}, {x, 1, ival, 1}, {y, 1, 6, 1}];
Tab2 = Table[{x, y1}, {x, 1, ival, 1}, {y1, 7, 8, 1}];

The values of columns are chosen as a toy example, there is no similar pattern in the actual tables that I use.

These tables have itot "blocks" with correspondingly 6 (Tab1) and 2 (Tab2) rows. I would like to join blocks from Tab1, Tab2 in one block, i.e. to produce the table TabTot with blocks containing 8 rows. The brute-force way is:

TabTot = Table[{Tab1[[i]][[1]], Tab1[[i]][[2]], Tab1[[i]][[3]], 
    Tab1[[i]][[4]], Tab1[[i]][[5]], Tab1[[i]][[6]], Tab2[[i]][[1]], 
    Tab2[[i]][[2]]}, {i, 1, Length[Tab1], 1}];

However, 1) it seems that this way is slower than it may be as it calls tables many times, 2) it requires tons of tedious repetitions of code, such as "Tab1[[i]][[1]]", which will be annoying in the case of many rows in blocks for instance.

Could you please tell me whether there is a more efficient way to join the tables?

$\endgroup$
1

4 Answers 4

8
$\begingroup$

You're looking for

TabTot = Transpose@Join[Transpose@Tab1, Transpose@Tab2]

More generally, Transpose is very useful when manipulating tables and higher-rank tensors.

$\endgroup$
11
$\begingroup$

One way is to use ArrayFlatten:

ArrayFlatten[{{Tab1, Tab2}}] === TabTot

(* True *)
$\endgroup$
4
$\begingroup$

I have chosen a smaller example for demo:

ival = 10^1;
Tab1 = Table[{x, y}, {x, 1, ival, 1}, {y, 1, 6, 1}]
Tab2 = Table[{x, y1}, {x, 1, ival, 1}, {y1, 7, 8, 1}]

tabRes = Join[Tab1[[#]], Tab2[[#]]] & /@ Range[Length@Tab1]

$$\left( \begin{array}{cccccccc} \{1,1\} & \{1,2\} & \{1,3\} & \{1,4\} & \{1,5\} & \{1,6\} & \{1,7\} & \{1,8\} \\ \{2,1\} & \{2,2\} & \{2,3\} & \{2,4\} & \{2,5\} & \{2,6\} & \{2,7\} & \{2,8\} \\ \{3,1\} & \{3,2\} & \{3,3\} & \{3,4\} & \{3,5\} & \{3,6\} & \{3,7\} & \{3,8\} \\ \{4,1\} & \{4,2\} & \{4,3\} & \{4,4\} & \{4,5\} & \{4,6\} & \{4,7\} & \{4,8\} \\ \{5,1\} & \{5,2\} & \{5,3\} & \{5,4\} & \{5,5\} & \{5,6\} & \{5,7\} & \{5,8\} \\ \{6,1\} & \{6,2\} & \{6,3\} & \{6,4\} & \{6,5\} & \{6,6\} & \{6,7\} & \{6,8\} \\ \{7,1\} & \{7,2\} & \{7,3\} & \{7,4\} & \{7,5\} & \{7,6\} & \{7,7\} & \{7,8\} \\ \{8,1\} & \{8,2\} & \{8,3\} & \{8,4\} & \{8,5\} & \{8,6\} & \{8,7\} & \{8,8\} \\ \{9,1\} & \{9,2\} & \{9,3\} & \{9,4\} & \{9,5\} & \{9,6\} & \{9,7\} & \{9,8\} \\ \{10,1\} & \{10,2\} & \{10,3\} & \{10,4\} & \{10,5\} & \{10,6\} & \{10,7\} & \{10,8\} \\ \end{array} \right)$$

$\endgroup$
4
$\begingroup$

Join with level specification 2 is as fast as ArrayFlatten which is faster than alternatives posted so far:

tabTot1 = Join[Tab1, Tab2, 2]; // RepeatedTiming // First
0.068
tabTot2 = ArrayFlatten[{{Tab1, Tab2}}]; // RepeatedTiming // First
0.071
tabTot3 = Transpose@Join[Transpose@Tab1, Transpose@Tab2]; // 
  RepeatedTiming // First
0.21
tabTot4 = Join[Tab1[[#]], Tab2[[#]]] & /@ Range[Length@Tab1]; // 
  RepeatedTiming // First
0.58
TabTot = Table[{Tab1[[i]][[1]], Tab1[[i]][[2]], Tab1[[i]][[3]], 
      Tab1[[i]][[4]], Tab1[[i]][[5]], Tab1[[i]][[6]], Tab2[[i]][[1]], 
      Tab2[[i]][[2]]}, {i, 1, Length[Tab1], 1}]; // 
  RepeatedTiming // First
1.68
tabTot1 == tabTot2 == tabTot3 == tabTot4 == TabTot
True
$\endgroup$

Your Answer

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

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