Jika Anda meniadakan array, elemen terendah menjadi elemen tertinggi dan sebaliknya. Oleh karena itu, indeks n
elemen tertinggi adalah:
(-avgDists).argsort()[:n]
Cara lain untuk bernalar tentang ini, seperti yang disebutkan dalam komentar , adalah untuk mengamati bahwa unsur-unsur besar akan menjadi yang terakhir dalam argumen. Jadi, Anda dapat membaca dari ekor argsort untuk menemukan n
elemen tertinggi:
avgDists.argsort()[::-1][:n]
Kedua metode adalah O (n log n) dalam kompleksitas waktu, karena argsort
panggilan adalah istilah yang dominan di sini. Tetapi pendekatan kedua memiliki keuntungan yang bagus: ia menggantikan negasi O (n) dari array dengan irisan O (1) . Jika Anda bekerja dengan array dalam loop kecil maka Anda mungkin mendapatkan beberapa keuntungan kinerja dari menghindari negasi itu, dan jika Anda bekerja dengan array besar maka Anda dapat menghemat penggunaan memori karena negasi membuat salinan seluruh array.
Perhatikan bahwa metode ini tidak selalu memberikan hasil yang setara: jika penerapan sortir yang stabil diminta argsort
, misalnya dengan melewati argumen kata kunci kind='mergesort'
, maka strategi pertama akan mempertahankan stabilitas penyortiran, tetapi strategi kedua akan merusak stabilitas (yaitu posisi yang sama barang akan terbalik).
Contoh waktu:
Menggunakan array kecil 100 float dan panjang 30 ekor, metode tampilan sekitar 15% lebih cepat
>>> 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)
Untuk array yang lebih besar, argsort dominan dan tidak ada perbedaan waktu yang signifikan
>>> 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)
Harap dicatat bahwa komentar dari nedim di bawah ini salah. Apakah memotong sebelum atau setelah membalikkan tidak membuat perbedaan dalam efisiensi, karena kedua operasi ini hanya berjalan dengan pandangan yang berbeda dari array dan tidak benar-benar menyalin data.
ids = np.array(avgDists).argsort()[-n:]
?