13
$\begingroup$

I have a matrix where every item in the matrix has its own brackets that I do not want. How can I remove the brackets around each item?

Here is the matrix shown in both displays

$\endgroup$
  • 1
    $\begingroup$ Try mat /. List[x__] /; Length[List[x]] == 1 :> x where mat is your matrix (I can't read which letter you're using in this image). $\endgroup$ – IPoiler Feb 7 '16 at 20:34
  • 4
    $\begingroup$ Flatten /@ matrix $\endgroup$ – garej Feb 8 '16 at 6:18
  • 1
    $\begingroup$ Related: (20180) $\endgroup$ – Mr.Wizard Feb 8 '16 at 9:10
  • 2
    $\begingroup$ Catenate /@ m is also a fast option. $\endgroup$ – garej Feb 8 '16 at 17:27
14
$\begingroup$

Lots of solutions. Time for a benchmark. My own contribution is Part:

m = {{{1}, {2}, {3}}, {{2}, {4}, {6}}};

m[[All, All, 1]];
{{1, 2, 3}, {2, 4, 6}}

Update: I made a complete mess of my earlier attempt at benchmarking. Here is a rewrite.

methods = Hold[Flatten /@ m, ArrayReshape[m, Most@Dimensions@m], 
   ArrayReshape[m, Dimensions[m][[1 ;; 2]]], Flatten[m, {Depth[m] - 1, 1}], 
   Apply[Sequence, m, {2}], Apply[Sequence, m, {-2}], Join @@@ m, m[[All, All, 1]], 
   Catenate /@ m];

names = {"Map[Flatten]", "ArrayReshape 1", "ArrayReshape 2", "Flatten w/ Depth", 
   "Sequence {2}", "Sequence {-2}", "Join", "Part", "Map[Catenate]"};

upk[{x_, y_}] := Table[{ToString[i*j]}, {i, x}, {j, y}];
pkd[{x_, y_}] := RandomReal[1, {x, y, 1}];

tab = 
 Table[
  List @@ First /@ RepeatedTiming /@ methods,
  {fn, {upk, pkd}},
  {shape, {{10, 100000}, {1000, 1000}, {100000, 10}}},
  {m, {fn[shape]}}
 ];

TableForm[
  Append[names] /@ (tab //. {x_List} :> x),
  TableHeadings -> {{"Unpacked", "Packed"}, {{10, 100000}, {1000, 1000}, {100000, 10}}},
  TableSpacing -> {5, 1, 0.5}
]

enter image description here
(Benchmark timings in 10.1.0 under Windows 7 x64.)

It seems that in most instances Part wins, but a few times Catenate edges it out.

$\endgroup$
  • 1
    $\begingroup$ @jjc385 Sorry, I was just being lazy. Actually really lazy as if the code I copied is actually what I ran the second test is a total mess. Earlier I had a comment "where's my coffee" -- I guess I really needed it! $\endgroup$ – Mr.Wizard Feb 8 '16 at 14:15
  • 1
    $\begingroup$ @jjc385 I rewrote the benchmark and got a different result. I hope I got it right this time but I am not certain I am still thinking clearly. Please let me know if you notice any stupid mistakes. $\endgroup$ – Mr.Wizard Feb 8 '16 at 15:01
  • 1
    $\begingroup$ It looks good to me, but then again I'm running on 2 hours of sleep and a can of soda at 7am ;) By the way, and I'm not suggesting you implement this here, do you know of a slick way to do something like highlighting the elements of a list, with the highlighting color changing based on their values? It would be a good way to instantly see the winner for tests like these. (I admit I ask more out of curiosity than practicality.) $\endgroup$ – jjc385 Feb 8 '16 at 15:43
  • 1
    $\begingroup$ @Mr.Wizard, would you mind to check this method: Catenate /@ m. It will not beat Part but I'm not sure about other options. $\endgroup$ – garej Feb 8 '16 at 16:52
  • 2
    $\begingroup$ @garej What I found interesting was that relative performance seemed to vary by system so much. It's nice to see a new function (Catenate) be an improvement once in a while. My last row is very different: 0.0044, 0.0063, 0.11. Note though that Catenate is not compilable, which is why it loses out to Flatten on longer lists; it also why mapping it unpacks the list (to level 1 only), making further processing less efficient (unless repacked). Join unpacks to level 2; Sequence unpacks the whole array. Not sure why a difference in timing is not reflected on Mr.Wizard's computer. $\endgroup$ – Michael E2 Feb 9 '16 at 13:52
14
$\begingroup$

Wrap the matrix rows with the the Flatten function

M = {{{1}, {2}, {3}, {4}}, {{5}, {6}, {7}, {8}}}

the matrix

To save time you can wrap your whole matrix using: Map[Flatten, <yourmatrix> ]

Map[Flatten,{{{1}, {2}, {3}, {4}}, {{5}, {6}, {7}, {8}}}]

the outermost list contains two elements (the rows). the Map function wraps these elements with the Flatten function

{{1, 2, 3, 4}, {5, 6, 7, 8}}

In Mathematica this is known as "nested" Lists. Flatten removes all wrappings of the List function until only one remains

To understand what the Map function does: Below is the "manual" approach without the Map function.

{  
 Flatten[{{1}, {2}, {3}, {4}}],

 Flatten[{{5}, {6}, {7}, {7}}]
}

As you are talking to an awesome machine called the Mathematica kernel you don't have to waste time writing things in long hand to make them readable (like you would for a slow-to-understand human reader of an essay or your future self reading your code).

hence Map[Flatten, Matrix] has the terse shorthand form Flatten /@ matrix

mentioned by @garej , @jjc385 and @Mr.Wizard below

$\endgroup$
  • 1
    $\begingroup$ As this answer is clearly geared for new users, I think this answer would be somewhat improved by mentioning the syntactic sugar Flatten /@ <matrix>. $\endgroup$ – jjc385 Feb 8 '16 at 13:18
  • $\begingroup$ (Is it polite/conventional to delete a comment such as mine above after the edit has been made?) $\endgroup$ – jjc385 Feb 8 '16 at 14:01
  • $\begingroup$ @jjc385 I have not observed a specific convention in that regard. The comments can serve as minor credit for the source of an edit, and I don't see anything wrong with that. However since you are mentioned by (nick)name in the answer now the comments seems redundant and I would probably delete it if it where mine. $\endgroup$ – Mr.Wizard Feb 16 '16 at 13:57
10
$\begingroup$

You can use ArrayReshape. Either

ArrayReshape[mat, Most@Dimensions@mat]

or

ArrayReshape[mat, Dimensions[mat][[1 ;; 2]]]

It will keep a packed array packed, too.

Mathematica graphics

$\endgroup$
  • $\begingroup$ Readers of this answer can find some further discussion of using ArrayReshape to remove unwanted singleton list wrappings, e.g., {a] or {{a, b, c}} in this answer $\endgroup$ – m_goldberg Aug 2 '16 at 12:51
7
$\begingroup$

Edit With m = RandomInteger[9, {3, 6, 1}]

Just for completeness:

Catenate /@ m

Just for diversity reasons

Apply[#&, m, {2}]
Apply[Sequence, m, {-2}]
Map[First, m, {2}]

Using @Mr.Wizard code I have updated the benchmark.

enter image description here

@MichaelE2 also noticed in comments that Catenate is not compilable.

$\endgroup$
  • 1
    $\begingroup$ I get similar results, to within a scaling factor for my slow CPU. Interesting that Join is much worse on packed arrays! $\endgroup$ – Simon Woods Feb 15 '16 at 20:22
  • $\begingroup$ @SimonWoods, MichaelE2 in a comment says "that Join unpacks to level 2. Sequence unpacks the whole array". He gets similar results. I'm surprized that Catenate behaves so different within packed group. $\endgroup$ – garej Feb 15 '16 at 21:12
6
$\begingroup$

You can also Apply Join at level 1 to your list:

m = RandomInteger[9, {2, 4, 1}]

{{{0}, {6}, {7}, {5}}, {{1}, {3}, {8}, {8}}}

Join @@@ m

{{0, 6, 7, 5}, {1, 3, 8, 8}}

$\endgroup$
  • 1
    $\begingroup$ thanks @Mr. Wizard. Terser yet m // ## & @@@ # & /@ # &:) $\endgroup$ – kglr Feb 8 '16 at 17:12
5
$\begingroup$

I suggest Flatten[m, {Depth[m] - 1, 1}], where m is the matrix in question.

For example,

SeedRandom[1]; m = RandomInteger[99, {4, 5, 1}]
{{{80}, {14}, {0}, {67}, {3}}, 
 {{65}, {23}, {97}, {68}, {74}}, 
 {{15},{24}, {4}, {90}, {83}}, 
 {{70}, {1}, {30}, {48}, {25}}}
Flatten[m, {Depth[m] - 1, 1}]
{{80, 14, 0, 67, 3}, 
 {65, 23, 97, 68, 74}, 
 {15, 24, 4, 90, 83}, 
 {70, 1, 30, 48, 25}}
$\endgroup$
2
$\begingroup$

...and of course, there's always Transpose[]:

Transpose[{{{1}, {2}, {3}}, {{2}, {4}, {6}}}, {2, 3, 1}] // First
   {{1, 2, 3}, {2, 4, 6}}

The Flatten[] equivalent is then

Flatten[{{{1}, {2}, {3}}, {{2}, {4}, {6}}}, {{1}, {3, 2}}]
   {{1, 2, 3}, {2, 4, 6}}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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