4

I have two matrices M1 and M2. Both have same number of columns but different number of rows. I want to make a new matrix M which should have 1st row form M1, second row form M2, third row form M1, fourth row from m2 and so on. For example,

M1 = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
M2 = {{10, 11, 12}, {13, 14, 15}, {16, 17, 18}, {19, 20, 21}, {22, 23, 24}};

and my final matrix should be

M = {{1, 2, 3}, {10, 11, 12}, {4, 5, 6}, {13, 14, 15}, {7, 8, 9}, {16, 17, 18}, {19, 20, 21}, {22, 23, 24}};

Please note length of each matrix is over 1000. Thank you for your help.

C. E.
  • 70,533
  • 6
  • 140
  • 264
ramesh
  • 2,309
  • 16
  • 29

2 Answers2

8
Join @@ Flatten[{M1, M2}, {{2}, {1}}]
(* {{1, 2, 3}, {10, 11, 12}, {4, 5, 6}, {13, 14, 15}, {7, 8, 9}, {16, 17,
   18}, {19, 20, 21}, {22, 23, 24}} *)

Reference for using the second argument of Flatten to transpose a ragged array.


Update: even shorter (big praise to Flatten):

Flatten[{M1, M2}, {2, 1}]
seismatica
  • 5,101
  • 1
  • 22
  • 33
2

Another method is with Riffle:

If[Length[M1] > Length[M2],
 Riffle[M1, M2, {2, 2 Length@M2, 2}],
 Riffle[M2, M1, {1, 2 Length@M1, 2}]
]

but the Flatten method is nicer, since it doesn't need the length-comparison logic.

Edited to reflect kguler's nice use of the third Riffle option.

evanb
  • 6,026
  • 18
  • 30
  • Very nice use of Riffle! It seems that your code will duplicate the {16, 17, 18}. I think using [[Length[M1]+1 ;; -1]] will fix that. Also, I think you can just use Riffle[M1, M2, {2, -1, 2}] though your use of Riffle is perfectly fine as it is. – seismatica Aug 08 '14 at 23:13
  • 2
    (+1) You can also use the simpler Riffle[M2,M1,{1,2 Length@M1,2}] as the 3rd argument of If. – kglr Aug 08 '14 at 23:23
  • @seismatica, you need the Length in the third argument and not -1 because otherwise it will repeat. Try, for example, with M2 = {{10,11,12}}; – evanb Aug 08 '14 at 23:50
  • @evanb Then it would default to your True case of If. I don't think you have to worry (in your older code) about riffling the longer M2 into the shorter M1 in the False case, since M2 will not run out and repeat. I think your old code (with my -1) was If[Length[M1] > Length[M2], Riffle[M1, M2, {2, 2 Length[M2], 2}], Join[Riffle[M1, M2, {2, -1, 2}], M2[[Length[M1] + 1 ;; -1]]]] – seismatica Aug 08 '14 at 23:55
  • My comment for the -1 was only for the False case. I'm sorry I wasn't clear. You're right, you need {2, 2Length@M2, 2}] for the True case in the old code, otherwise M2 would repeat. However, this also means that you can use Riffle[M2, M1, {1, -1, 2}] for your True case in the new code using @Pickett's trick of Riffle at the first position. – seismatica Aug 09 '14 at 00:03