# How to create a matrix of paired values from two matrices?

I have two matrices. They are,

m1={{a,b},{c,d}};
m2={{w,x},{y,z}};


I want to create a matrix of paired values that looks like this,

{{{a, w}, {b, x}}, {{c, y}, {d, z}}}


My equation for doing so looks like this,

Transpose /@ Transpose@{m1, m2}


and it works well; however, I thought I could use Map to accomplish the same thing at two different levels of the input. I have been unsuccessful in doing so. I have tried things like,

Map[Transpose, {m1, m2}, {0, 1}]


which results in,

{{{a, c}, {w, y}}, {{b, d}, {x, z}}}


which is clearly not what I want.

Is there a way to use Map in the above fashion and not call Transpose twice as I have done in the successful example?

P.S. I have seen this example; however, the output format is incorrect for what I want. Yes, you could recreate the matrix dimensions with Partition; however, I am looking for a more minimal expression.

I reviewed the following answers for speed using Timing.

Timing[Flatten[{m1,m2},{{2},{3}}]]][[1]]

(* 0.000021 *)

Timing[Transpose[{m1,m2},{3,1,2}]][[1]]

(* 0.000038 *)

Timing[MapThread[List,{m1,m2},2]][[1]]

(* 8.*10^-6 *)

• Thanks for the edits @xzczd. Commented Oct 11, 2022 at 21:45

MapThread[List, {m1, m2}, 2]


{{{a, w}, {b, x}}, {{c, y}, {d, z}}}

More alternatives that yield the same answer:

Table[Transpose@{m1[[i]], m2[[i]]}, {i, 1, Length[m1]}]

• Works with ArrayReshape[List@Flatten[{m1, m2}, {{2, 3}}], Array[2 &, 3]]. Commented Oct 11, 2022 at 16:25
• @xzczd thanks for spotting that. Not sure how I missed it :/
– bmf
Commented Oct 11, 2022 at 17:12
• @E.Chan-López still in the process of...paperwork is killing me
– bmf
Commented Oct 11, 2022 at 17:12
• Thanks @bmf, I played with MapThread but did not use the List function and I ran into trouble with MapThread removing the Head. With Map, I tried keeping the Head using Head->True; however, that gave me strange results. I think your answer best responds to the spirit of my question. Commented Oct 11, 2022 at 21:28
– bmf
Commented Oct 12, 2022 at 8:24

Since particular use of Transpose is shown, let me show the particular use of Flatten:

Flatten[{m1, m2}, {{2}, {3}}]


• I'd accept this answer too if I could accept multiple answers. Commented Oct 11, 2022 at 21:31

Easier than using Map is to just use the other form of Transpose:

Transpose[{m1, m2}, {3, 1, 2}]


If you really wanted to do a Map-ish thing, MapThread might be easier:

MapThread[Transpose@*List, {m1, m2}]

• (+1) nice to see that particular use of Transpose
– bmf
Commented Oct 11, 2022 at 16:10
• Thanks @lericr. This is, I think, the most elegant answer. I played around with trying to move the different levels but my intuition for this is poor. Commented Oct 11, 2022 at 21:24
• I'd accept this answer too if I could accept multiple answers. Commented Oct 11, 2022 at 21:31

As long as it is symbolic:

(m1 + m2) /. Plus -> List


Or its twin brother:

m1 m2 /. Times -> List


Result:

{{{a, w}, {b, x}}, {{c, y}, {d, z}}}

Just another way using Outer:

Table[Outer[List, m1, m2][[i, j, i, j]], {i, 1, 2}, {j, 1, 2}]
(*{{{a, w}, {b, x}}, {{c, y}, {d, z}}}*)


Function[{x, y}, {x, y}, Listable][m1, m2]


This started as

SetAttributes[f, Listable];
f[m1, m2] /. f -> List


Then I just turned it into an explicit function. This should avoid the problem Syed identified of needing to be symbolic.

EDIT

Okay, a bit more terse:

Function[, {##}, Listable][m1, m2]

• (+1) Nice, Indeed! Commented Oct 11, 2022 at 22:45
m1 = {{a, b}, {c, d}};

m2 = {{w, x}, {y, z}};


Using MapApply (new in 13.1)

MapApply[List] /@ (m1 m2)


{{{a, w}, {b, x}}, {{c, y}, {d, z}}}