Ordenar NumPy float array columna por columna

Siguiendo este truco para capturar entradas únicas para una matriz NumPy, ahora tengo una matriz de dos columnas, básicamente de pares con el primer elemento en el rango [0.9: 0.02: 1.1] y el segundo elemento en el rango [1.5: 0.1: 2.0 ]. Llamemos a esto A Actualmente, es completamente sin clasificar, es decir

 In [111]: A Out[111]: array([[ 1.1 , 1.9 ], [ 1.06, 1.9 ], [ 1.08, 1.9 ], [ 1.08, 1.6 ], [ 0.9 , 1.8 ], ... [ 1.04, 1.6 ], [ 0.96, 2. ], [ 0.94, 2. ], [ 0.98, 1.9 ]]) 

Me gustaría ordenarlo para que cada fila aumente primero en la segunda columna, luego en la primera. es decir

 array([[ 0.9 , 1.5 ], [ 0.9 , 1.6 ], [ 0.9 , 1.7 ], [ 0.9 , 1.9 ], [ 0.9 , 1.9 ], [ 0.9 , 2. ], [ 0.92, 1.5 ], ... [ 1.08, 2. ], [ 1.1 , 1.5 ], [ 1.1 , 1.6 ], [ 1.1 , 1.7 ], [ 1.1 , 1.8 ], [ 1.1 , 1.9 ], [ 1.1 , 2. ]]) 

pero no puedo encontrar un algoritmo de clasificación que da a ambos. Como se sugiere aquí , probé A[A[:,0].argsort()] y A[A[:,1].argsort()] , pero solo ordenan una columna cada una. También he intentado aplicar ambos pero pasa lo mismo.

Pido disculpas si me he perdido algo simple pero he estado buscando esto por un tiempo ahora …

numpy.lexsort funcionará aquí:

 A[np.lexsort(AT)] 

Debe transponer A antes de pasárselo a lexsort porque cuando pasa una matriz 2d, espera ordenar por filas (última fila, segunda última fila, etc.).

La forma alternativa, quizás un poco más clara, es pasar las columnas explícitamente:

 A[np.lexsort((A[:, 0], A[:, 1]))] 

Aún debe recordar que lexsort se clasifica por la última clave primero (probablemente hay una buena razón para esto; es lo mismo que realizar una clasificación estable en claves sucesivas).

Lo siguiente funcionará, pero podría haber una manera más rápida:

 A = np.array(sorted(A,key=tuple)) 

Simplemente reemplace todo (incluyendo la parte única con) por A siendo 2D:

 A = np.ascontiguousarray(A) # just to make sure... A = A.view([('', A.dtype)] * A.shape[1]) A = np.unique(A) # And if you want the old view: A = A.view(A.dtype[0]).reshape(-1,len(A.dtype)) 

Espero que no estés usando la solución set de la pregunta vinculada a menos que no te importe demasiado la velocidad. El lexsort etc., es generalmente bueno, pero aquí no es necesario ya que la ordenación predeterminada funcionará (si se trata de una nueva versión)


Edición: una vista diferente (con mucho el mismo resultado), pero un poco más elegante tal vez porque no se necesita una nueva forma:

 A = A.view([('', A.dtype, A.shape[0])]) A = np.unique(A) # And to go back A = A.view(A.dtype[0].base)