¿Cómo puedo ordenar una matriz en NumPy por la enésima columna?
Por ejemplo,
a = array([[9, 2, 3],
[4, 5, 6],
[7, 0, 5]])
Me gustaría ordenar las filas por la segunda columna, de modo que regrese:
array([[7, 0, 5],
[9, 2, 3],
[4, 5, 6]])
np.sort(a, axis=0)
que sería una solución satisfactoria para la matriz dada. Sugerí una edición con un mejor ejemplo, pero fue rechazado, aunque en realidad la pregunta sería mucho más clara. El ejemplo debería ser algo así comoa = numpy.array([[1, 2, 3], [6, 5, 2], [3, 1, 1]])
con la salida deseadaarray([[3, 1, 1], [1, 2, 3], [6, 5, 2]])
Respuestas:
La respuesta de @steve es en realidad la forma más elegante de hacerlo.
Para la forma "correcta", vea el argumento de palabra clave de orden de numpy.ndarray.sort
Sin embargo, deberá ver su matriz como una matriz con campos (una matriz estructurada).
La forma "correcta" es bastante fea si no definiste inicialmente tu matriz con campos ...
Como ejemplo rápido, para ordenarlo y devolver una copia:
Para ordenarlo en el lugar:
@ Steve realmente es la forma más elegante de hacerlo, que yo sepa ...
La única ventaja de este método es que el argumento "ordenar" es una lista de los campos para ordenar la búsqueda. Por ejemplo, puede ordenar por la segunda columna, luego la tercera columna, luego la primera columna proporcionando orden = ['f1', 'f2', 'f0'].
fuente
ValueError: new type not compatible with array.
float
? ¿Debo cambiar algo?a = np.array([['a',1,2,3],['b',4,5,6],['c',0,0,1]])
¿qué enfoque debo seguir?np.argsort
sí mismos pueden ocupar bastante memoria, y además de eso, la indexación con una matriz también generará una copia de la matriz que se está ordenando.Supongo que esto funciona:
a[a[:,1].argsort()]
Esto indica la segunda columna de
a
y ordenarla en función de ella en consecuencia.fuente
1
aquí? el índice por el que se ordenará?[:,1]
indica la segunda columna dea
.a[a[:,1].argsort()[::-1]]
np.sort
o no?ind = np.argsort( a[:,1] ); a = a[ind]
Puede ordenar en varias columnas según el método de Steve Tjoa utilizando una ordenación estable como mergesort y ordenando los índices de las columnas menos significativas a las más significativas:
Esto ordena por columna 0, luego 1, luego 2.
fuente
En caso de que alguien quiera usar la clasificación en una parte crítica de sus programas, aquí hay una comparación de rendimiento para las diferentes propuestas:
Entonces, parece que indexar con argsort es el método más rápido hasta ahora ...
fuente
Desde el wiki de documentación de Python , creo que puedes hacer:
El resultado es:
fuente
De la lista de correo NumPy , aquí hay otra solución:
fuente
a[np.lexsort(a.T[cols])]
. dondecols=[1]
en la pregunta original.Tuve un problema similar.
Mi problema:
Quiero calcular un SVD y necesito ordenar mis valores propios en orden descendente. Pero quiero mantener el mapeo entre valores propios y vectores propios. Mis valores propios estaban en la primera fila y el vector propio correspondiente debajo de ellos en la misma columna.
Entonces, quiero ordenar una matriz bidimensional en forma de columna por la primera fila en orden descendente.
Mi solución
Entonces, ¿cómo funciona esto?
a[0,]
es solo la primera fila por la que quiero ordenar.Ahora uso argsort para obtener el orden de los índices.
Lo uso
[::-1]
porque necesito un orden descendente.Por último, uso
a[::, ...]
para obtener una vista con las columnas en el orden correcto.fuente
Un
lexsort
ejemplo un poco más complicado : descender en la primera columna, ascender secundariamente en la segunda. Los trucoslexsort
son que se ordena en filas (de ahí el.T
) y da prioridad a la última.fuente
Aquí hay otra solución considerando todas las columnas (forma más compacta de la respuesta de JJ );
Ordenar con lexsort,
Salida:
fuente
Simplemente usando sort, use el número de coloumn basado en el que desea ordenar.
fuente
Es una pregunta antigua, pero si necesita generalizar esto a matrices de más de 2 dimensiones, esta es la solución que puede generalizarse fácilmente:
Esta es una exageración para dos dimensiones y
a[a[:,1].argsort()]
sería suficiente según la respuesta de @ steve, sin embargo, esa respuesta no puede generalizarse a dimensiones superiores. Puede encontrar un ejemplo de matriz 3D en esta pregunta.Salida:
fuente