Nếu bạn phủ nhận một mảng, các phần tử thấp nhất sẽ trở thành các phần tử cao nhất và ngược lại. Do đó, các chỉ số của các n
yếu tố cao nhất là:
(-avgDists).argsort()[:n]
Một cách khác để lý giải về điều này, như được đề cập trong các ý kiến , là quan sát rằng các yếu tố lớn đang đến cuối cùng trong argsort. Vì vậy, bạn có thể đọc từ phần đuôi của argsort để tìm các n
phần tử cao nhất:
avgDists.argsort()[::-1][:n]
Cả hai phương thức là O (n log n) về độ phức tạp thời gian, bởi vì argsort
cuộc gọi là thuật ngữ chi phối ở đây. Nhưng cách tiếp cận thứ hai có một lợi thế tốt: nó thay thế một phủ định O (n) của mảng bằng một lát O (1) . Nếu bạn đang làm việc với các mảng nhỏ bên trong các vòng lặp thì bạn có thể đạt được một số hiệu suất từ việc tránh sự phủ định đó và nếu bạn đang làm việc với các mảng lớn thì bạn có thể tiết kiệm sử dụng bộ nhớ vì việc phủ định tạo ra một bản sao của toàn bộ mảng.
Lưu ý rằng các phương thức này không phải lúc nào cũng cho kết quả tương đương: nếu yêu cầu triển khai sắp xếp ổn định argsort
, ví dụ: bằng cách chuyển đối số từ khóa kind='mergesort'
, thì chiến lược đầu tiên sẽ duy trì sự ổn định sắp xếp, nhưng chiến lược thứ hai sẽ phá vỡ sự ổn định (nghĩa là các vị trí bằng nhau các mặt hàng sẽ được đảo ngược).
Thời gian ví dụ:
Sử dụng một mảng nhỏ gồm 100 phao và đuôi dài 30, phương thức xem nhanh hơn khoảng 15%
>>> avgDists = np.random.rand(100)
>>> n = 30
>>> timeit (-avgDists).argsort()[:n]
1.93 µs ± 6.68 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
>>> timeit avgDists.argsort()[::-1][:n]
1.64 µs ± 3.39 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
>>> timeit avgDists.argsort()[-n:][::-1]
1.64 µs ± 3.66 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Đối với các mảng lớn hơn, argsort chiếm ưu thế và không có sự khác biệt đáng kể về thời gian
>>> avgDists = np.random.rand(1000)
>>> n = 300
>>> timeit (-avgDists).argsort()[:n]
21.9 µs ± 51.2 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> timeit avgDists.argsort()[::-1][:n]
21.7 µs ± 33.3 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> timeit avgDists.argsort()[-n:][::-1]
21.9 µs ± 37.1 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Xin lưu ý rằng nhận xét từ nedim dưới đây là không chính xác. Việc cắt bớt trước hay sau khi đảo ngược sẽ không có sự khác biệt về hiệu quả, vì cả hai thao tác này chỉ tạo ra một cách nhìn khác nhau về mảng và không thực sự sao chép dữ liệu.
ids = np.array(avgDists).argsort()[-n:]
sao?