1
$\begingroup$

I have a matrix like below:

mat = {{{a}, {b}, {c}, {d}}, {{a}, {b}, {c}, {d}}}

I want to change it to

{{a, b, c, d}, {a, b, c, d}}

I have tried Flatten function, but was unable to achieve my goal.

$\endgroup$
  • 2
    $\begingroup$ Flatten[#, 1] & /@ mat which is just Map[Flatten[#, 1] &, mat]. See also Pure Functions. $\endgroup$ – corey979 Feb 25 '19 at 14:08
  • 3
    $\begingroup$ Flatten /@ mat $\endgroup$ – J42161217 Feb 25 '19 at 14:09
  • 3
    $\begingroup$ Join @@@ mat.. $\endgroup$ – OkkesDulgerci Feb 25 '19 at 14:16
  • 3
    $\begingroup$ ArrayReshape[mat,{2,4}] $\endgroup$ – N.J.Evans Feb 25 '19 at 14:17
3
$\begingroup$

There are many ways (shown by people in the comments). Personally, I find this one to be the cleanest:

mat[[All, All, 1]]

Take All rows, All columns, and then the 1st element from the list within.

|improve this answer|||||
$\endgroup$
2
$\begingroup$

Partition is your friend here, when things get confusing. First Flatten it all the way out.

res=Flatten[mat]

{a, b, c, d, a, b, c, d}

Now Partition into blocks of 4 elements

Partition[res,4]

{{a, b, c, d}, {a, b, c, d}}


Edit

As a performance check, I ran the following tests on the methods in the initial comments, and @Szabolcs's answer. Listed in rank ordering of timing performance. ArrayReshape for the win, but Flatten-Partition in 2nd. EDIT: Surprisingly, it was a little faster to break up the Flatten-Partition into two steps rather than embed them.

mat = RandomInteger[100, {10,000,000, 4, 1}];

AbsoluteTiming[res1 = ArrayReshape[mat, {Length[mat], 4}];]
{0.23, Null}

AbsoluteTiming[res = Flatten@mat; Partition[res, 4];]
{.37, Null}

AbsoluteTiming[Partition[Flatten@mat, 4];]
{0.41, Null}

AbsoluteTiming[res4 = Flatten[mat, {{1}, {2, 3}}];]
{0.523814, Null}

AbsoluteTiming[mat[[All, All, 1]];]
{0.63, Null}

AbsoluteTiming[Flatten /@ mat;]
{1.69, Null}

AbsoluteTiming[Map[Flatten[#, 1] &, mat];]
{1.74, Null}

AbsoluteTiming[Flatten[#, 1] & /@ mat;]
{1.77, Null}

AbsoluteTiming[Join @@@ mat;]
{19.4, Null}
|improve this answer|||||
$\endgroup$
  • $\begingroup$ Uhh, why the negative votes? $\endgroup$ – MikeY Feb 25 '19 at 14:13
  • 2
    $\begingroup$ Negative votes probably because your solution is not a recommended way. It goes too far with Flatten and then backtracks with Partition, for which (i) you need the original sublist length 4, and (ii) you assume that all sublists are of equal length. See the above comments for direct solutions without backtracking. $\endgroup$ – Roman Feb 25 '19 at 14:21
  • 1
    $\begingroup$ OK, but I think you've read more into his question than he put in there. While the methods in the comments above all work, many of them require digging into the docs to understand why exactly they work (awesome learning exercise for the novice). Clever but not intuitive. The Flatten-Partition approach is a no-brainer that allows you to implement and move on, and when you are dealing with 2 x 4 matrices... $\endgroup$ – MikeY Feb 25 '19 at 14:35
  • 2
    $\begingroup$ For completeness, please test Flatten[mat, {{1}, {2, 3}}] as well. $\endgroup$ – J. M.'s technical difficulties Feb 25 '19 at 16:00
  • $\begingroup$ Done, you get the Bronze medal. :) $\endgroup$ – MikeY Feb 25 '19 at 16:37

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