12

I need to "riffle" two matrices; COLUMNWISE.

Say that we have:

M1 = {{1, 7, 13, 19, 25, 31}, {2, 8, 14, 20, 26, 32}, {3, 9, 15, 21, 27, 33},
      {4, 10, 16, 22, 28, 34}, {5, 11, 17, 23, 29, 35}, {6, 12, 18, 24, 30, 36}};

and:

M2 = {{A, G, M}, {B, H, N}, {C, I, O}, {D, J, P}, {E, K, Q}, {F, L, R}};

I need to get a third matrix:

1, A, 7,  G, 13, M, 19, 25, 31
2, B, 8,  H, 14, N, 20, 26, 32
3, C, 9,  I, 15, O, 21, 27, 33
4, D, 10, J, 16, P, 22, 28, 34
5, E, 11, K, 17, Q, 23, 29, 35
6, F, 12, L, 18, R, 24, 30, 36

In general; the two matrices M1 and M2 have the same number of rows. On the other hand; the second matrix M2 may have fewer columns than the first matrix M1; (or both matrices could have the same number of columns).

How can I riffle them to get the above third matrix?

Thank you.

march
  • 23,399
  • 2
  • 44
  • 100

3 Answers3

12

Another option:

MapThread[Join @@ Flatten[{##}, {2}] &, {M1, M2}]

And a better option:

Flatten[{M1, M2}, {3, 1}]\[Transpose]

Finally a single-command from WReach in the comments:

Flatten[{M1, M2}, {{2}, {3, 1}}]

Recommended reading:

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • Hi Mr.Wizard, +1 If you delete the last R at the end of M2 your first command still works but the second one does not. – bobbym Aug 26 '16 at 02:12
  • Just an oddity but the first solution can handle M2 with different length rows. – bobbym Aug 26 '16 at 02:19
  • 3
    +1. Another alternative: Flatten[{M1, M2}, {{2}, {3, 1}}]. This will also handle the case proposed by @bobbym. – WReach Aug 26 '16 at 02:46
  • @WReach Nice! I tried to do that all within Flatten and failed. I am not sure what I tried now, but whatever it did not work. – Mr.Wizard Aug 26 '16 at 05:46
7
M1 = {{1, 7, 13, 19, 25, 31}, {2, 8, 14, 20, 26, 32}, {3, 9, 15, 21, 
    27, 33}, {4, 10, 16, 22, 28, 34}, {5, 11, 17, 23, 29, 35}, {6, 12,
     18, 24, 30, 36}};
M2 = {{a, g, m}, {b, h, n}, {c, i, o}, {d, j, p}, {e, k, g}, {f, l, r}};


Riffle[##, 2 {1, Length@#2, 1}] & @@@ Transpose[{M1, M2}]

{{1, a, 7, g, 13, m, 19, 25, 31},
{2, b, 8, h, 14, n, 20, 26, 32},
{3, c, 9, i, 15, o, 21, 27, 33},
{4, d, 10, j, 16, p, 22, 28, 34},
{5, e, 11, k, 17, g, 23, 29, 35},
{6, f, 12, l, 18, r, 24, 30, 36}}

kglr
  • 394,356
  • 18
  • 477
  • 896
  • Nice use of Riffle. A distinct advantage of this method over Flatten is that the sublists remain packed when possible, e.g. two Integer arrays. – Mr.Wizard Aug 26 '16 at 05:41
5

One way:

MapThread[
  Join[Riffle[#1[[;; Length@#2]], #2], #1[[1 + Length@#2 ;;]]] &,
  {M1, M2}
 ]

Or, similarly,

Block[{PlaceHolder},
  MapThread[
    Riffle[#1, PadRight[#2, Length@#1, PlaceHolder]] &,
    {M1, M2}
   ] /. PlaceHolder -> (## &[])
 ]

Or, if the rows all have the same length within each list, this also works:

Transpose@Join[
  Riffle[#1[[;; Length@#2]], #2], #1[[1 + Length@#2 ;;]]
 ] & @@ {Transpose@M1, Transpose@M2}
march
  • 23,399
  • 2
  • 44
  • 100
  • 3
    @GilmarRodriguezPierluissi. Note that it is a bad idea to use capitalized symbols for user-defined functions and variables. Note that C, D, E, I, K, N, O are all reserved symbols in Mathematica, which is why they are colored differently, and that can lead to problems. – march Aug 25 '16 at 22:53
  • Thank you all for all your excellent replies! You ought to try "riffling" in Excel with large number of columns involved. You are saving me (and others, I'm sure) a lot of perspiration with your inspiration! I'm very grateful! – Gilmar Rodriguez Pierluissi Aug 26 '16 at 13:25
  • Talking about large matrices; when I attempted your riffle command scenarios on two large matrices; I get all sorts of errors. Please, try: Matrix1 = Table[NumberForm[N[(10 i + 9 j)/70, 3], {4, 2}], {i, 33}, {j, 18}]; Matrix2 = Table[NumberForm[N[(12 i + 17 j)/70, 3], {4, 2}], {i, 33}, {j, 13}]; – Gilmar Rodriguez Pierluissi Aug 26 '16 at 14:39
  • @GilmarRodriguezPierluissi. I tried your examples, and they worked fine for me. Did you perhaps reverse the order of the matrices? That matters a lot. – march Aug 26 '16 at 17:06
  • Oh, gee wheeze! I was using the labels Matrix 1 and Matrix 2 instead of M1 and M2. Lord have mercy! Must be Friday!... :-) Thank you! – Gilmar Rodriguez Pierluissi Aug 26 '16 at 18:04