2010-03-20 12 views
12

ein Array ‚a‘ Da würde Ich mag die Anordnung von Spalten sortieren „sortieren (a, Achse = 0)“ ein paar Sachen auf das Array tun und dann die Sortierung rückgängig machen. Damit meine ich nicht die Art und Weise, wie jedes Element verschoben wurde. Ich nehme an, dass argsort() das ist, was ich brauche, aber es ist mir nicht klar, wie man ein Array mit den Ergebnissen von argsort() sortiert oder, was noch wichtiger ist, das umgekehrte/umgekehrte von argsort()rückgängig machen oder umgekehrt argsort(), Python

Hier ist ein wenig mehr Detail

ich habe ein Array ein, die Form (a) = RXC ich brauche jede Spalte

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

nun jede Reihe im Durchschnitt zu sortieren

aSortRM = asort.mean(axis=1) 

nun jede col in einer Reihe mit der Reihe ersetzen mich ein. gibt es einen besseren Weg, als diese

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

Jetzt muss ich die Sorte, die ich im ersten Schritt tat rückgängig zu machen. ????

+1

Warum können Sie nicht einfach eine Kopie des Arrays erstellen: 'a.copy()' vor irgendwelchen Transformationen oder verwenden Sie 'aSort = numpy .sort (axis = 0) '(wird die sortierte Kopie zurückgegeben)? btw, 'a.sort()' gibt nichts zurück, daher gibt es keinen Sinn, seinen Rückgabewert zuzuweisen. – jfs

+0

@ J.F. Sebastian, Danke du hast recht Ich habe es behoben – Vincent

Antwort

4

Ich bin nicht sicher, wie sie am besten in numpy zu tun, aber in reinem Python würde die Argumentation sein:

aargsort ist eine Permutation von range(len(a)) Halten Sie sagt, wo die Gegenstände von aSort herkam - ähnlich wie in reinem Python:

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

dh das erste Argument von sorted(x)x[2] sein, die zweiten x[4], und so weiter.

So ist die sortierte Version angegeben, können Sie das Original durch rekonstruieren „setzen Einzelteile zurück, woher sie kamen“:

>>> 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'] 
>>> 

Natürlich werden straffer und schnellere Wege, um dies in numpy auszudrücken (Leider kenne ich Inside-out nicht so sehr wie ich Python selbst ;-), aber ich hoffe, dass dies hilft, indem ich die zugrunde liegende Logik der "Dinge an Ort und Stelle bringen" -Operation, die Sie ausführen müssen, aufzeigen muss.

1

war ich nicht in der Lage Ihrem Beispiel zu folgen, aber die abstraktere Problem - d. H, wie ein Array dann in umgekehrte Reihenfolge sortieren zu sortieren - ist unkompliziert.

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) 

zu "rekonstruieren" A von A_sorted ist trivial, weil daran denkt, dass Sie ein Index-Array verwendet ('ndx'), um das Array in erster Linie zu sortieren.

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

Mit anderen Worten war die 4. Reihe in A_sorted die erste Zeile in der ursprünglichen Anordnung, A, usw.

+0

Ich möchte eigentlich jede Spalte einzeln sortieren, ich korrigiere meinen Code oben, aber ich muss mit np.sort (A, axis = 0) arbeiten, damit das inex np.argsort wäre (x, axis = 0) – Vincent

30

Es gibt wahrscheinlich bessere Lösungen für das Problem, das Sie tatsächlich als diese versuchen zu lösen (Durchführen einer argsort in der Regel die Notwendigkeit, tatsächlich Art ausschließt), aber hier geht:

>>> 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

Für alle, die noch auf der Suche für eine Antwort:

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, um das Spiel zu spät, aber hier:

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 

Im Grunde Argsort den Argsort, weil das n-te Element der umgekehrten Sortierung ist J [n] = k: I [k] = n. Das heißt, ich [J [n]] = n, also J sortiert I.

+0

Dies ist bei weitem die beste Lösung – simeon

Verwandte Themen