2010-03-20 87 views
12

給定一個數組'''我想排序列「sort(a,axis = 0)」做一些東西到數組,然後撤消排序。由此我不意味着重新排序,而是基本顛倒每個元素的移動方式。我假設我需要的是argsort(),但我不清楚如何使用argsort()的結果對數組進行排序,或者更重要的是應用argsort()的反向/反向。這裏有一些更詳細的內容撤消或反向argsort(),python

我有一個陣列的,形狀(A)= RXC我需要每一列

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

現在平均每行

aSortRM = asort.mean(axis=1) 

現在與行替換每個山口連續排序我一個。 有比這

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

現在我需要撤消排序我在第一個步驟做了一個更好的辦法。 ????

+1

爲什麼不能在任何轉換或使用'aSort = numpy之前創建數組的副本:'a.copy .sort(axis = 0)'(這將返回排序後的副本)?順便說一句,'a.sort()'不會返回任何內容,因此沒有必要指定它的返回值。 – jfs 2010-03-20 16:05:37

+0

@ J.F。塞巴斯蒂安,謝謝你是對的我修正了它 – Vincent 2010-03-20 16:46:34

回答

4

我不知道如何最好地做到這一點在numpy,但是,在純Python,推理是:

aargsort持有的range(len(a))置換,告訴您的aSort物品是從哪裏來的 - 很像,在純Python:

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

即,sorted(x)第一個參數將是x[2],第二個x[4],等等。

所以給出的排序版本,您可以通過重建原始「把物品帶回他們來自何處」:

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

當然也有將是更嚴格和更快速的方式在numpy來表達這種(不幸的是,我不知道里面的內容,就像我知道Python本身;-),但我希望這可以通過展示「需要執行的操作」的基本邏輯來幫助您完成。

1

我無法效仿你的例子,但更抽象的問題 - 即如何對數組進行排序然後顛倒排序 - 很直接。

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) 

到「重建」從A_sorted A是微不足道的,因爲記住你使用的索引陣列(「NDX」),以在第一位置對數組進行排序。

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

換句話說,A_sorted中的第4行是原始數組中的第1行,A等。

+0

我實際上想單獨對每列進行排序,我在頂部修正了我的代碼,但是我需要使用np.sort(A,axis = 0),所以這個不可能是np.argsort (x,axis = 0) – Vincent 2010-03-20 16:51:38

30

有給你實際上是試圖解決比這個(執行argsort通常排除需要實際排序)的問題可能是更好的解決方案,但是在這裏你去:

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

對於那些仍在尋找一個答案:

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

超級太遲了,但在這裏:

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 

基本上,argsort argsort是因爲反向排序的第n個元素是J [n] = k:I [k] = n。也就是說,I [J [n]] = n,所以J排序我。

+0

這是迄今爲止最好的解決方案 – simeon 2018-02-24 07:02:01