2010-03-20 35 views
12

Cho một mảng 'a' Tôi muốn sắp xếp mảng theo cột "sắp xếp (a, trục = 0)" làm một số nội dung cho mảng và sau đó hoàn tác sắp xếp. Bằng cách đó tôi không có nghĩa là sắp xếp lại nhưng về cơ bản đảo ngược như thế nào mỗi yếu tố đã được di chuyển. Tôi giả sử argsort() là những gì tôi cần nhưng không rõ ràng với tôi cách sắp xếp một mảng với kết quả của argsort() hoặc quan trọng hơn là áp dụng đảo ngược/nghịch đảo của argsort()undo hoặc reverse argsort(), python

Dưới đây là chi tiết hơn một chút

tôi có một mảng một, hình dạng (a) = rXc tôi cần phải sắp xếp mỗi cột

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

nay trung bình mỗi hàng

aSortRM = asort.mean(axis=1) 

nay thay thế mỗi col trong một hàng với hàng tôi một. có cách nào tốt hơn so với số này

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

Bây giờ tôi cần hoàn tác sắp xếp mà tôi đã thực hiện trong bước đầu tiên. ????

+1

Tại sao bạn không thể tạo bản sao của mảng: 'a.copy()' trước bất kỳ phép biến đổi nào hoặc sử dụng 'aSort = numpy .sort (axis = 0) '(sẽ trả về bản sao đã sắp xếp)? btw, 'a.sort()' trả về không có gì do đó không có điểm để gán giá trị trả về của nó. – jfs

+0

@ J.F. Sebastian, Cảm ơn bạn là đúng Tôi cố định nó – Vincent

Trả lời

4

Tôi không chắc chắn cách tốt nhất để làm điều đó trong numpy, nhưng, bằng Python tinh khiết, lý do sẽ là:

aargsort đang nắm giữ một hoán vị của range(len(a)) nói cho bạn nơi các mặt hàng của aSort đến từ - nhiều như thế, bằng Python tinh khiết:

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

tức, đối số đầu tiên của sorted(x) sẽ x[2], thứ hai một x[4], và vân vân.

Vì vậy, cho phiên bản sắp xếp, bạn có thể tái tạo lại bản gốc bằng cách "đặt mục trở lại nơi họ đến từ":

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

Tất nhiên có sẽ được cách chặt chẽ hơn và nhanh hơn để thể hiện điều này trong numpy (mà tiếc là tôi không biết bên trong-ra nhiều như tôi biết Python chính nó ;-), nhưng tôi hy vọng điều này sẽ giúp bằng cách hiển thị logic cơ bản của việc "đưa mọi thứ trở lại tại chỗ" hoạt động bạn cần phải thực hiện.

1

Tôi không thể làm theo ví dụ của bạn, nhưng vấn đề trừu tượng hơn - tức là, cách sắp xếp một mảng rồi đảo ngược sắp xếp - rất đơn giản.

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) 

Để "xây dựng lại" A từ A_sorted là tầm thường vì nhớ rằng bạn đã sử dụng một mảng chỉ mục ('ndx') để sắp xếp mảng ở vị trí đầu tiên.

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

Nói cách khác, hàng thứ 4 trong A_sorted là hàng thứ nhất trong mảng ban đầu, A, v.v.

+0

Tôi thực sự muốn sắp xếp từng cột riêng lẻ, tôi sửa mã của tôi ở đầu nhưng tôi cần phải làm việc với np.sort (A, axis = 0) để inex sẽ là np.argsort (x, trục = 0) – Vincent

30

Có nhiều giải pháp có lẽ tốt hơn cho vấn đề bạn đang thực sự cố gắng để giải quyết hơn thế này (thực hiện một argsort thường ngăn cản sự cần thiết để thực sự loại), nhưng ở đây bạn đi:

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

Đối với tất cả những người vẫn tìm kiếm cho một câu trả lời:

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

Siêu muộn để các trò chơi, nhưng ở đây:

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 

Về cơ bản, argsort argsort vì phần tử thứ n của kiểu đảo ngược là J [n] = k: I [k] = n. Tức là, tôi [J [n]] = n, vì vậy J sắp xếp I.

+0

Đây là giải pháp tốt nhất – simeon