2010-03-18 21 views
12

Al manipular matrices, a menudo es conveniente cambiar su forma. Por ejemplo, para convertir una matriz de tamaño M x N en un vector de longitud NX M. En MATLAB existe una función reshape:Cómo remodelar matrices en Mathematica

RESHAPE (X, M, N) devuelve la matriz M-por-N cuyos elementos se toman en forma de columna desde X. Se produce un error si X no tiene elementos M * N.

En el caso de la conversión entre una matriz y vector puedo utilizar la función de Mathematica Flatten que se aprovecha de la representación lista anidada de Mathematica para matrices. Como un ejemplo rápido, supongamos que tengo una matriz X:

4x4 matrix

Con Aplanar [X] puedo conseguir el vector {1,2,3, ..., 16}. Pero lo que sería mucho más útil es algo parecido a la aplicación de Matlab cambio de forma (X, 2,8) lo que resultaría en la siguiente matriz:

4x4 matrix

Esto permitiría la creación de matrices arbitrarias, siempre y cuando las dimensiones son iguales a N * M. Por lo que puedo decir, no hay nada construido que me pregunte si alguien no ha codificado una función de remodelación propia.

Respuesta

18
Reshape[mtx_, _, n_] := Partition[Flatten[mtx], n] 
3

Sé que esto es un hilo viejo, pero por el bien de los archivos y las búsquedas de Google Tengo una manera más general que permite una longitud m * n * ... lista para ser convertido en un m * n * ... array:

Reshape[list_, shape__] := Module[{i = 1}, 
    NestWhile[Partition[#, shape[[i]]] &, list, ++i <= Length[shape] &] 
    ] 

Ej:

In:= Reshape[Range[8], {2, 2, 2}] 

Out:= {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}} 
+0

Nota: Esta solución incorpora las últimas dos dimensiones, por lo que no funciona del todo. – Guillochon

4
Reshape[list_, dimensions_] := 
First[Fold[Partition[#1, #2] &, Flatten[list], Reverse[dimensions]]] 

Ejemplo de Uso:

In: Reshape[{1,2,3,4,5,6},{2,3}] 

Out: {{1,2,3},{4,5,6}} 

Esto funciona con matrices de profundidad arbitraria.

10

ArrayReshape hace exactamente eso.

+0

tenga en cuenta que esto no estaba disponible cuando se formuló la pregunta, pero es probable que sea la mejor respuesta hoy ... (nuevo en la versión 9) – agentp

+0

@george yes; ¡eso está en el espíritu del sitio para promover respuestas adaptativas! –

0

Ahora también hay una nueva función ArrayReshape [].

Ejemplo:

{{1, 2, 3}, {4, 5, 6}} // MatrixForm 

ArrayReshape[{{1, 2, 3}, {4, 5, 6}}, {3, 2}] // MatrixForm 
+0

¿cómo cambio la forma por columna? es decir, ¿los elementos bajan verticalmente y luego pasan a la siguiente columna? –