una tutorial transpuesta multiplicar matriz matrices libreria español array python sorting numpy

python - tutorial - Ordenando una matriz numpy 2D por múltiples ejes



numpy tutorial español pdf (7)

EDITAR: eliminó la mala respuesta.

Aquí hay una manera de hacerlo usando una matriz estructurada intermedia:

from numpy import array a = array([[3, 2], [6, 2], [3, 6], [3, 4], [5, 3]]) b = a.flatten() b.dtype = [(''x'', ''<i4''), (''y'', ''<i4'')] b.sort() b.dtype = ''<i4'' b.shape = a.shape print b

que da el resultado deseado:

[[3 2] [3 4] [3 6] [5 3] [6 2]]

Sin embargo, no estoy seguro de si esta es la mejor manera de hacerlo.

Tengo una matriz numpy 2D de forma (N, 2) que tiene N puntos (coordenadas xey). Por ejemplo:

array([[3, 2], [6, 2], [3, 6], [3, 4], [5, 3]])

Me gustaría ordenarlo de manera que mis puntos estén ordenados por coordenadas x, y luego por y en los casos donde la coordenada x sea la misma. Entonces, la matriz de arriba debería verse así:

array([[3, 2], [3, 4], [3, 6], [5, 3], [6, 2]])

Si esta fuera una lista de Python normal, simplemente definiría un comparador para hacer lo que quiero, pero hasta donde puedo decir, la función de ordenamiento de numpy no acepta comparadores definidos por el usuario. ¿Algunas ideas?

EDIT: gracias por las ideas! Configuré un caso de prueba rápido con 1000000 puntos enteros aleatorios y comparaté los que podía ejecutar (lo siento, no puedo actualizar el numpy en este momento).

Mine: 4.078 secs mtrw: 7.046 secs unutbu: 0.453 secs


El paquete numpy_indexed (descargo de responsabilidad: soy su autor) se puede usar para resolver este tipo de problemas de procesado en nd-array de una manera eficiente totalmente vectorizada:

import numpy_indexed as npi npi.sort(a) # by default along axis=0, but configurable


El título dice "ordenar matrices 2D". Aunque el interlocutor utiliza una matriz en forma de (N,2) , es posible generalizar la solución de unutbu para trabajar con cualquier matriz (N,M) , ya que eso es lo que las personas realmente podrían estar buscando.

Uno podría transpose la matriz y usar la notación de lexsort con el step negativo para pasar todas las columnas a la orden lexsort en orden inverso:

>>> import numpy as np >>> a = np.random.randint(1, 6, (10, 3)) >>> a array([[4, 2, 3], [4, 2, 5], [3, 5, 5], [1, 5, 5], [3, 2, 1], [5, 2, 2], [3, 2, 3], [4, 3, 4], [3, 4, 1], [5, 3, 4]]) >>> a[np.lexsort(np.transpose(a)[::-1])] array([[1, 5, 5], [3, 2, 1], [3, 2, 3], [3, 4, 1], [3, 5, 5], [4, 2, 3], [4, 2, 5], [4, 3, 4], [5, 2, 2], [5, 3, 4]])


Encontré una forma de hacerlo:

from numpy import array a = array([(3,2),(6,2),(3,6),(3,4),(5,3)]) array(sorted(sorted(a,key=lambda e:e[1]),key=lambda e:e[0]))

Es bastante terrible tener que ordenar dos veces (y usar la función sorted pitón simple en lugar de una especie de numpy más rápido), pero encaja muy bien en una línea.


Estaba luchando con lo mismo y solo recibí ayuda y resolví el problema. Funciona sin problemas si su matriz tiene nombres de columna (matriz estructurada) y creo que esta es una forma muy sencilla de ordenar utilizando la misma lógica que Excel:

array_name[array_name[[''colname1'',''colname2'']].argsort()]

Tenga en cuenta los doble paréntesis que encierran los criterios de clasificación. Y, por supuesto, puede usar más de 2 columnas como criterios de clasificación.


Puede usar np.complex_sort . Esto tiene el efecto secundario de cambiar sus datos a punto flotante, espero que eso no sea un problema:

>>> a = np.array([[3, 2], [6, 2], [3, 6], [3, 4], [5, 3]]) >>> atmp = np.sort_complex(a[:,0] + a[:,1]*1j) >>> b = np.array([[np.real(x), np.imag(x)] for x in atmp]) >>> b array([[ 3., 2.], [ 3., 4.], [ 3., 6.], [ 5., 3.], [ 6., 2.]])


Usando lexsort :

import numpy as np a = np.array([(3, 2), (6, 2), (3, 6), (3, 4), (5, 3)]) ind = np.lexsort((a[:,1],a[:,0])) a[ind] # array([[3, 2], # [3, 4], # [3, 6], # [5, 3], # [6, 2]])

a.ravel() devuelve una vista si a es C_CONTIGUOUS . Si eso es cierto, el método de @ ars , ligeramente modificado mediante el uso de ravel lugar de flatten , ofrece una buena manera de ordenar a in situ :

a = np.array([(3, 2), (6, 2), (3, 6), (3, 4), (5, 3)]) dt = [(''col1'', a.dtype),(''col2'', a.dtype)] assert a.flags[''C_CONTIGUOUS''] b = a.ravel().view(dt) b.sort(order=[''col1'',''col2''])

Como b es una vista de a , sorting b ordena a :

print(a) # [[3 2] # [3 4] # [3 6] # [5 3] # [6 2]]