Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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.

share|improve this question

2 Answers 2

up vote 6 down vote accepted
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}]
share|improve this answer
1  
+1 nice usage of Flatten! –  Pickett Aug 8 at 22:07
    
Thanks! I discovered it from a SE Q&A and I'm trying to dig it out to give proper credit. –  seismatica Aug 8 at 22:08
1  
+1 One of the fastest answers ever given :) –  eldo Aug 8 at 22:09
1  
@seismatica Thanks for quick reply. I verified your codes in my data. It works so well. Thank you so much. You saved my life! ::::)))) –  rka Aug 8 at 22:57
    
You're welcome! Glad it helped. –  seismatica Aug 8 at 22:58

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.

share|improve this answer
    
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 8 at 23:13
1  
(+1) You can also use the simpler Riffle[M2,M1,{1,2 Length@M1,2}] as the 3rd argument of If. –  kguler Aug 8 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 8 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 8 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 9 at 0:03

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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