Tại sao numpy lại đưa ra kết quả này:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
khi tôi mong đợi nó làm điều này:
[3 2 0 1]
Rõ ràng là sự hiểu biết của tôi về chức năng này còn thiếu sót.
Tại sao numpy lại đưa ra kết quả này:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
khi tôi mong đợi nó làm điều này:
[3 2 0 1]
Rõ ràng là sự hiểu biết của tôi về chức năng này còn thiếu sót.
Câu trả lời:
[2, 3, 1, 0]
chỉ ra rằng phần tử nhỏ nhất ở chỉ số 2, nhỏ nhất tiếp theo ở chỉ số 3, sau đó là chỉ số 1, rồi đến chỉ số 0.
Có một số cách để có được kết quả mà bạn đang tìm kiếm:
import numpy as np
import scipy.stats as stats
def using_indexed_assignment(x):
"https://stackoverflow.com/a/5284703/190597 (Sven Marnach)"
result = np.empty(len(x), dtype=int)
temp = x.argsort()
result[temp] = np.arange(len(x))
return result
def using_rankdata(x):
return stats.rankdata(x)-1
def using_argsort_twice(x):
"https://stackoverflow.com/a/6266510/190597 (k.rooijers)"
return np.argsort(np.argsort(x))
def using_digitize(x):
unique_vals, index = np.unique(x, return_inverse=True)
return np.digitize(x, bins=unique_vals) - 1
Ví dụ,
In [72]: x = np.array([1.48,1.41,0.0,0.1])
In [73]: using_indexed_assignment(x)
Out[73]: array([3, 2, 0, 1])
Điều này kiểm tra rằng tất cả chúng đều tạo ra cùng một kết quả:
x = np.random.random(10**5)
expected = using_indexed_assignment(x)
for func in (using_argsort_twice, using_digitize, using_rankdata):
assert np.allclose(expected, func(x))
Các %timeit
điểm chuẩn IPython này gợi ý cho các mảng lớn using_indexed_assignment
là nhanh nhất:
In [50]: x = np.random.random(10**5)
In [66]: %timeit using_indexed_assignment(x)
100 loops, best of 3: 9.32 ms per loop
In [70]: %timeit using_rankdata(x)
100 loops, best of 3: 10.6 ms per loop
In [56]: %timeit using_argsort_twice(x)
100 loops, best of 3: 16.2 ms per loop
In [59]: %timeit using_digitize(x)
10 loops, best of 3: 27 ms per loop
Đối với các mảng nhỏ, using_argsort_twice
có thể nhanh hơn:
In [78]: x = np.random.random(10**2)
In [81]: %timeit using_argsort_twice(x)
100000 loops, best of 3: 3.45 µs per loop
In [79]: %timeit using_indexed_assignment(x)
100000 loops, best of 3: 4.78 µs per loop
In [80]: %timeit using_rankdata(x)
100000 loops, best of 3: 19 µs per loop
In [82]: %timeit using_digitize(x)
10000 loops, best of 3: 26.2 µs per loop
Cũng lưu ý rằng stats.rankdata
cung cấp cho bạn nhiều quyền kiểm soát hơn đối với cách xử lý các phần tử có giá trị bằng nhau.
argsort
trả về các chỉ số của mảng đã sắp xếp. Chỉ số của các chỉ số được sắp xếp là thứ hạng. Đây là những gì cuộc gọi thứ hai để argsort
trả về.
Như tài liệu cho biết argsort
:
Trả về các chỉ số sẽ sắp xếp một mảng.
Điều đó có nghĩa là phần tử đầu tiên của argsort là chỉ số của phần tử sẽ được sắp xếp đầu tiên, phần tử thứ hai là chỉ số của phần tử nên được xếp thứ hai, v.v.
Những gì bạn có vẻ muốn là thứ tự xếp hạng của các giá trị, là thứ được cung cấp bởi scipy.stats.rankdata
. Lưu ý rằng bạn cần suy nghĩ về những gì sẽ xảy ra nếu có ràng buộc trong hàng ngũ.
numpy.argsort (a, axis = -1, kind = 'quicksort', order = None)
Trả về các chỉ số sẽ sắp xếp một mảng
Thực hiện sắp xếp gián tiếp dọc theo trục đã cho bằng cách sử dụng thuật toán được chỉ định bởi từ khóa kind. Nó trả về một mảng các chỉ số có cùng hình dạng với dữ liệu chỉ mục đó dọc theo trục đã cho theo thứ tự được sắp xếp.
Hãy xem xét một ví dụ trong python, có danh sách các giá trị như
listExample = [0 , 2, 2456, 2000, 5000, 0, 1]
Bây giờ chúng ta sử dụng hàm argsort:
import numpy as np
list(np.argsort(listExample))
Đầu ra sẽ là
[0, 5, 6, 1, 3, 2, 4]
Đây là danh sách các chỉ số của giá trị trong listVí dụ nếu bạn ánh xạ các chỉ số này với các giá trị tương ứng thì chúng ta sẽ nhận được kết quả như sau:
[0, 0, 1, 2, 2000, 2456, 5000]
(Tôi thấy hàm này rất hữu ích ở nhiều nơi, ví dụ: Nếu bạn muốn sắp xếp danh sách / mảng nhưng không muốn sử dụng hàm list.sort () (tức là không thay đổi thứ tự của các giá trị thực trong danh sách), bạn có thể sử dụng hàm này chức năng.)
Để biết thêm chi tiết, hãy tham khảo liên kết này: https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.argsort.html
input:
import numpy as np
x = np.array ([1.48,1.41,0.0,0.1])
x.argsort (). argsort ()
đầu ra:
mảng ([3, 2, 0, 1])
Đầu tiên, nó được sắp xếp theo thứ tự mảng. Sau đó, tạo một mảng với chỉ số ban đầu của mảng.
Chỉ muốn đối chiếu trực tiếp hiểu biết ban đầu của OP với cách triển khai thực tế với mã.
numpy.argsort
được định nghĩa như vậy đối với mảng 1D:
x[x.argsort()] == numpy.sort(x) # this will be an array of True's
OP ban đầu nghĩ rằng nó được định nghĩa như vậy đối với mảng 1D:
x == numpy.sort(x)[x.argsort()] # this will not be True
Lưu ý: Mã này không hoạt động trong trường hợp chung (chỉ hoạt động cho 1D), câu trả lời này hoàn toàn mang tính chất minh họa.
x[x.argsort()]
không nhất thiết phải giống như np.sort(x)
. Trên thực tế, nó không nhất thiết phải có hình dạng giống nhau. Hãy thử điều này với một mảng 2D. Điều này chỉ xảy ra với các mảng 1D.
[3 2 0 1]
sẽ là câu trả lời chính xác?