Cómo aplanar solo algunas dimensiones de una matriz numpy

5 minutos de lectura

avatar de usuario
IssamLaradji

¿Existe una forma rápida de “subaplanar” o aplanar solo algunas de las primeras dimensiones en una matriz numpy?

Por ejemplo, dada una matriz numpy de dimensiones (50,100,25)las dimensiones resultantes serían (5000,25)

  • Esto podría ayudar a stackoverflow.com/questions/13990465/3d-numpy-array-to-2d

    – Ankur Ankan

    12 de septiembre de 2013 a las 7:16

  • Necesita un curso de actualización sobre el corte de matriz numpy ndarray. También conocido como indexación de matrices multidimensionales, consulte: docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html Array divide tu ndarray usando corchetes y usa el delimitador de coma para separar la cantidad de cada dimensión que deseas. Se verá algo como (no exactamente) esto: your_array[50:100, 7, :] que aplana el objeto 3d a 2d, usando solo el segmento número 7 para la segunda dimensión.

    –Eric Leschinski

    31 de agosto de 2017 a las 23:38


  • ^ Los sectores solo toman un subconjunto, el cartel quiere conservar todos los puntos de datos. Supongo que te refieres array[0:50,7,:] que da el tamaño (50,25)descartando el 99% de los datos.

    – Sherman

    19 de mayo a las 6:39

avatar de usuario
Alejandro

Echa un vistazo a numpy.reformar .

>>> arr = numpy.zeros((50,100,25))
>>> arr.shape
# (50, 100, 25)

>>> new_arr = arr.reshape(5000,25)
>>> new_arr.shape   
# (5000, 25)

# One shape dimension can be -1. 
# In this case, the value is inferred from 
# the length of the array and remaining dimensions.
>>> another_arr = arr.reshape(-1, arr.shape[-1])
>>> another_arr.shape
# (5000, 25)

  • Tales soluciones me parecen un poco poco elegantes, ya que requieren información redundante. Desearía que hubiera una manera de hacer esto que solo requiriera especificar el subconjunto de dimensiones, algo así como arr.flatten(dimensions=(0, 1)).

    – Denziloe

    14 de agosto de 2020 a las 1:01

  • @Denziloe uno no puede simplemente ‘aplanar’ una dimensión arbitraria de un ndarray sin especificar en qué dimensión se plegarán los datos adicionales. Tomemos, por ejemplo, un ndarray de 2x2x3, aplanar la última dimensión puede producir un 2×6 o 6×2, por lo que la información no es redundante. Puede especificar la dimensión con un -1: Desde numpy.reformar Una dimensión de forma puede ser -1. En este caso, el valor se deduce de la longitud de la matriz y las dimensiones restantes. Entonces, un 2x2xN remodelado a 2Nx2 se ve así:arr.reshape((-1,2)).

    – אלימלך שרייבר

    14 de febrero de 2021 a las 10:38


  • @Denziloe Una forma de lograr esto puede ser algo como arr.reshape(arr.shape[0] * arr.shape[1], arr.shape[2])

    – Adrián Pavao

    2 de julio de 2021 a las 12:03

  • @אלימלךשרייבר Divertido, la antorcha parece manejar esto de alguna manera: pytorch.org/docs/stable/generated/torch.flatten.html 😉

    – Sebastián Hoffmann

    7 de mayo a las 14:28

  • @SebastianHoffmann, tonto aplanar también se las arreglaría. Flatten, como lo implica el nombre de la función, aplana el tensor/ndarray en una matriz 1-D. Por lo tanto, *no hay ambigüedad que deba resolverse. Mientras que el tema discutido aquí es el aplanamiento de una sola dimensión, por ejemplo, un 6-D en un tensor/ndarray de 5-D. Reforma de antorchanecesita la misma especificación en este sentido.

    – אלימלך שרייבר

    8 de mayo a las 20:42


Una ligera generalización de la respuesta de Alexander: np.reshape puede tomar -1 como argumento, lo que significa “tamaño total de la matriz dividido por el producto de todas las demás dimensiones enumeradas”:

por ejemplo, para aplanar todo menos la última dimensión:

>>> arr = numpy.zeros((50,100,25))
>>> new_arr = arr.reshape(-1, arr.shape[-1])
>>> new_arr.shape
# (5000, 25)

Una ligera generalización de la respuesta de Peter: puede especificar un rango sobre la forma de la matriz original si desea ir más allá de las matrices tridimensionales.

por ejemplo, para aplanar todo menos el último dos dimensiones:

arr = numpy.zeros((3, 4, 5, 6))
new_arr = arr.reshape(-1, *arr.shape[-2:])
new_arr.shape
# (12, 5, 6)

EDITAR: una ligera generalización de mi respuesta anterior: por supuesto, también puede especificar un rango al comienzo de la remodelación:

arr = numpy.zeros((3, 4, 5, 6, 7, 8))
new_arr = arr.reshape(*arr.shape[:2], -1, *arr.shape[-2:])
new_arr.shape
# (3, 4, 30, 7, 8)

  • Ya han pasado más de dos años… ¡Necesitamos otra ligera generalización! 😉

    – Litio

    27 de marzo de 2020 a las 13:44

Un enfoque alternativo es utilizar numpy.resize() como en:

In [37]: shp = (50,100,25)
In [38]: arr = np.random.random_sample(shp)
In [45]: resized_arr = np.resize(arr, (np.prod(shp[:2]), shp[-1]))
In [46]: resized_arr.shape
Out[46]: (5000, 25)

# sanity check with other solutions
In [47]: resized = np.reshape(arr, (-1, shp[-1]))
In [48]: np.allclose(resized_arr, resized)
Out[48]: True

avatar de usuario
Sherman

numpy.vstack es perfecto para esta situación

import numpy as np
arr = np.ones((50,100,25))
np.vstack(arr).shape
> (5000, 25)

prefiero usar stack, vstack o hstack sobre reshape porque reshape simplemente escanea los datos y parece aplicar fuerza bruta en la forma deseada. Esto puede ser problemático si, por ejemplo, va a tomar promedios de columna.

Aquí hay una ilustración de lo que quiero decir. Supongamos que tenemos la siguiente matriz

>>> arr.shape
(2, 3, 4)
>>> arr 
array([[[1, 2, 3, 4],
        [1, 2, 3, 4],
        [1, 2, 3, 4]],

       [[7, 7, 7, 7],
        [7, 7, 7, 7],
        [7, 7, 7, 7]]])

Aplicamos ambos métodos para obtener una matriz de forma (3,8)

>>> arr.reshape((3,8)).shape
(3, 8)
>>> np.hstack(arr).shape 
(3, 8)

Sin embargo, si observamos cómo se han reconfigurado en cada caso, la hstack nos permitiría tomar sumas de columnas que también podríamos haber calculado a partir de la matriz original. Con remodelar esto no es posible.

>>> arr.reshape((3,8))
array([[1, 2, 3, 4, 1, 2, 3, 4],
       [1, 2, 3, 4, 7, 7, 7, 7],
       [7, 7, 7, 7, 7, 7, 7, 7]])
>>> np.hstack(arr)
array([[1, 2, 3, 4, 7, 7, 7, 7],
       [1, 2, 3, 4, 7, 7, 7, 7],
       [1, 2, 3, 4, 7, 7, 7, 7]])

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad