12
$\begingroup$

This question already has an answer here:

If I have an array A, for which Dimensions[A] is {9, 9, 1, 1, 3, 4}, how can I convert A' into an array with dimensions {9, 9, 3, 4}?

I think there is a built-in function for this, but I can't remember its name.

$\endgroup$

marked as duplicate by Michael E2, m_goldberg, Yves Klett, Kuba, Artes Nov 29 '13 at 15:08

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • $\begingroup$ What is meant by conversion of dimension ? Repositioning element or just removing 1 from list ? $\endgroup$ – Rorschach Nov 23 '13 at 9:13
  • $\begingroup$ It is just the same array logically; however, mathematica's Dimensions[] function will identify them as different arrays with different dimensions. $\endgroup$ – LCFactorization Nov 23 '13 at 9:17
  • $\begingroup$ E.g, If I have {{a,b},{c,d}}, it is {2,2} in sizes; sometimes it can also be {2,2,1,1,1}; How to make sure mathematica's Dimensions only obtain the simplest result {2,2}? $\endgroup$ – LCFactorization Nov 23 '13 at 9:18
  • $\begingroup$ Flatten does work, but it is complicate this way; there should be a simpler way with only one simple Function but I forget the name. $\endgroup$ – LCFactorization Nov 23 '13 at 9:27
13
$\begingroup$

You could get the array's dimensions, remove the 1's and use that in ArrayReshape:

array = Array[f, {9, 9, 1, 1, 3, 4}];
new = ArrayReshape[array, Dimensions[array] ~DeleteCases~ 1];
Dimensions[new]
(*  {9, 9, 3, 4} *)

If efficiency is not important you could use a replacement rule:

new = array //. {x_} :> x
Dimensions[new]
(*  {9, 9, 3, 4} *)
$\endgroup$
  • $\begingroup$ Thanks. It seems I was confused by Matlab's "squeeze" which removes singleton dimensions while Mathematica doesnot have such a function. $\endgroup$ – LCFactorization Nov 24 '13 at 0:01
  • $\begingroup$ ArrayReshape is a thing now? Sweet! $\endgroup$ – Pillsy Nov 24 '13 at 4:02
3
$\begingroup$
array = Array[f, {9, 9, 1, 1, 3, 4}];
Dimensions[array]

{9,9,1,1,3,4}

newArray=Flatten[array , {{1}, {2}, {5}, {6, 3, 4}}];  
 Dimensions[newArray]

{9,9,3,4}

$\endgroup$
  • $\begingroup$ Thank you. The desired solution should be that, the user don't have to use the original array's dimension information. If these are available, I would prefer to use ArrayReshape[] $\endgroup$ – LCFactorization Nov 23 '13 at 9:36
3
$\begingroup$

Another way to use Flatten is to collect the trivial (single-element) levels with the first nontrivial level:

flattenTrivialLevels[array_] := 
 Flatten[array, 
   Flatten[{Position[#, _?(# > 1 &), 1, 1], Position[#, 1]} &@ Dimensions[array]]]

OP's test case (compared with Simon Woods' elementary replacement method):

array = RandomInteger[10, {9, 9, 1, 1, 3, 4}];
flat = flattenTrivialLevels[array];
new = array //. {x_} :> x;
Dimensions[flat]
flat === new

(* {9, 9, 3, 4} *)
(* True *)

The Flatten command being used is Flatten[array, {1, 3, 4}].

An arbitrary variation:

array = RandomInteger[10, {1, 9, 1, 9, 1, 1, 3, 1, 1, 1, 4}];
flat = flattenTrivialLevels[array];
new = array //. {x_} :> x;
Dimensions[flat]
flat === new

(* {9, 9, 3, 4} *)
(* True *)
$\endgroup$

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