2010-03-20 12 views
12

Dato un array 'a' vorrei ordinare l'array in base alle colonne "sort (a, axis = 0)" fare un po 'di cose nell'array e quindi annullare l'ordinamento. Con ciò non intendo riordinare ma sostanzialmente invertire il modo in cui ogni elemento è stato spostato. Suppongo che argsort() sia ciò di cui ho bisogno ma non mi è chiaro come ordinare un array con i risultati di argsort() o più importante applicare l'inverso/inverso di argsort()annulla o inverti argsort(), python

Ecco un piccolo dettaglio

ho un array una forma (a) = RXC devo ordinare ogni colonna

aargsort = a.argsort(axis=0) # May use this later 
aSort = a.sort(axis=0) 

ora media ogni fila

aSortRM = asort.mean(axis=1) 

ora sostituire ogni col in una riga con la riga me un. c'è un modo migliore di questo

aWithMeans = ones_like(a) 
for ind in range(r) # r = number of rows 
    aWithMeans[ind]* aSortRM[ind] 

ora ho bisogno di annullare il genere che ho fatto nella prima fase. ????

+1

Perché non puoi semplicemente fare una copia dell'array: 'a.copy()' prima di qualsiasi trasformazione o usare 'aSort = numpy .sort (axis = 0) '(che restituirà una copia ordinata)? btw, 'a.sort()' non restituisce nulla, quindi non c'è alcun motivo per assegnare il suo valore di ritorno. – jfs

+0

@ J.F. Sebastian, grazie hai ragione l'ho risolto – Vincent

risposta

4

non sono sicuro il modo migliore per farlo in numpy, ma, in puro Python, il ragionamento sarebbe:

aargsort è in possesso di una permutazione di range(len(a)) che ti dice dove le voci di aSort venuto da - molto simile, in puro Python:

>>> x = list('ciaobelu') 
>>> r = range(len(x)) 
>>> r.sort(key=x.__getitem__) 
>>> r 
[2, 4, 0, 5, 1, 6, 3, 7] 
>>> 

per esempio, il primo argomento di sorted(x) sarà x[2], la seconda x[4], e così via.

Quindi, dato la versione ordinata, è possibile ricostruire l'originale di "mettere oggetti indietro da dove sono venuti":

>>> s = sorted(x) 
>>> s 
['a', 'b', 'c', 'e', 'i', 'l', 'o', 'u'] 
>>> original = [None] * len(s) 
>>> for i, c in zip(r, s): original[i] = c 
... 
>>> original 
['c', 'i', 'a', 'o', 'b', 'e', 'l', 'u'] 
>>> 

Naturalmente ci stanno per essere modi più strette e più veloci per esprimere questo in numpy (che sfortunatamente non conosco interiormente tanto quanto conosco Python stesso ;-), ma spero che ciò aiuti a mostrare la logica sottostante all'operazione "rimettere le cose a posto" che è necessario eseguire.

1

Non ero in grado di seguire il tuo esempio, ma il problema più astratto - cioè, come ordinare una matrice e invertire l'ordinamento - è semplice.

import numpy as NP 
# create an 10x6 array to work with 
A = NP.random.randint(10, 99, 60).reshape(10, 6) 
# for example, sort this array on the second-to-last column, 
# breaking ties using the second column (numpy requires keys in 
# "reverse" order for some reason) 
keys = (A[:,1], A[:,4]) 
ndx = NP.lexsort(keys, axis=0) 
A_sorted = NP.take(A, ndx, axis=0) 

di "ricostruire" A da A_sorted è banale, perché ricordate che si è utilizzato un array indice ('NDX') per ordinare l'array, in primo luogo.

# ndx array for example above: array([6, 9, 8, 0, 1, 2, 4, 7, 3, 5]) 

In altre parole, il 4 ° riga A_sorted stata la prima riga del vettore originale, A, etc.

+0

In realtà voglio ordinare ogni singola colonna, correggo il mio codice in alto ma ho bisogno di lavorare con np.sort (A, axis = 0) così l'inex sarebbe np.argsort (x, axis = 0) – Vincent

30

ci sono soluzioni probabilmente migliore al problema in realtà si sta cercando di risolvere di questo (l'esecuzione di un argsort solito preclude la necessità di realtà sorta), ma qui si va:

>>> import numpy as np 
>>> a = np.random.randint(0,10,10) 
>>> aa = np.argsort(a) 
>>> aaa = np.argsort(aa) 
>>> a # original 
array([6, 4, 4, 6, 2, 5, 4, 0, 7, 4]) 
>>> a[aa] # sorted 
array([0, 2, 4, 4, 4, 4, 5, 6, 6, 7]) 
>>> a[aa][aaa] # reversed 
array([6, 4, 4, 6, 2, 5, 4, 0, 7, 4]) 
7

Per tutti coloro ancora alla ricerca per una risposta:

In [135]: r = rand(10) 

In [136]: i = argsort(r) 

In [137]: r_sorted = r[i] 

In [138]: i_rev = zeros(10, dtype=int) 

In [139]: i_rev[i] = arange(10) 

In [140]: allclose(r, r_sorted[i_rev]) 

Out[140]: True 
1

Super ritardo al gioco, ma qui:

import numpy as np 
N = 1000 # or any large integer 
x = np.random.randn(N) 
I = np.argsort(x) 
J = np.argsort(I) 
print(np.allclose(x[I[J]] , x)) 
>> True 

Fondamentalmente, argsort l'argomento perché l'ennesimo elemento dell'ordinamento inverso è J [n] = k: I [k] = n. Cioè, I [J [n]] = n, quindi J sorts I.

+0

Questa è di gran lunga la soluzione migliore – simeon