¿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)
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)
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
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]])
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