Pertimbangkan kode berikut:
avgDists = np.array([1, 8, 6, 9, 4])
ids = avgDists.argsort()[:n]
Ini memberi saya indeks n
elemen terkecil. Apakah mungkin untuk menggunakan yang sama ini argsort
dalam urutan menurun untuk mendapatkan indeks n
elemen tertinggi?
ids = np.array(avgDists).argsort()[-n:]
?[3, 1, 2]
. Baris Anda menghasilkan[2, 1, 3]
(jika n == 3 sebagai contoh)ids = np.array(avgDists).argsort()[-n:][::-1]
. Masalahnya adalah menghindari membuat salinan dari seluruh daftar, yang adalah apa yang Anda dapatkan ketika Anda menambahkannya-
di depannya. Tidak relevan untuk contoh kecil OP, bisa untuk kasus yang lebih besar.np.array(avgDists).argsort()[::-1][:n]
akan melakukannya. Juga, jika Anda akan menggunakan numpy, tetaplah numpy. Pertama-tama ubah daftar menjadi sebuah array:avgDist=np.array(avgDists)
lalu ubah menjadiavgDist.argsort()[::-1][:n}
Jawaban:
Jika Anda meniadakan array, elemen terendah menjadi elemen tertinggi dan sebaliknya. Oleh karena itu, indeks
n
elemen tertinggi adalah: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: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 kuncikind='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
Untuk array yang lebih besar, argsort dominan dan tidak ada perbedaan waktu yang signifikan
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.
sumber
np.array(avgDists).argsort()[:-n][::-1]
Sama seperti Python, dalam
[::-1]
membalik array yang dikembalikan olehargsort()
dan[:n]
memberikan n elemen terakhir:Keuntungan dari metode ini
ids
adalah pandangan para avgDists:(The 'OWNDATA' menjadi False menunjukkan ini adalah tampilan, bukan salinan)
Cara lain untuk melakukan ini adalah sesuatu seperti:
Masalahnya adalah cara kerjanya adalah membuat negatif dari setiap elemen dalam array:
ANd membuat salinan untuk melakukannya:
Jadi, jika Anda menghitung waktu masing-masing, dengan kumpulan data yang sangat kecil ini:
Metode tampilan jauh lebih cepat (dan menggunakan 1/2 memori ...)
sumber
Anda dapat menggunakan perintah flip
numpy.flipud()
ataunumpy.fliplr()
untuk mendapatkan indeks dalam urutan menurun setelah mengurutkan menggunakanargsort
perintah. Itulah yang biasanya saya lakukan.sumber
Alih-alih menggunakan
np.argsort
Anda bisa menggunakannp.argpartition
- jika Anda hanya memerlukan indeks elemen n terendah / tertinggi.Itu tidak perlu mengurutkan seluruh array tetapi hanya bagian yang Anda butuhkan tetapi perhatikan bahwa "pesanan di dalam partisi Anda" tidak ditentukan, jadi sementara itu memberikan indeks yang benar mereka mungkin tidak dipesan dengan benar:
sumber
Anda bisa membuat salinan array dan kemudian mengalikan setiap elemen dengan -1.
Akibatnya elemen sebelum terbesar akan menjadi yang terkecil.
Induktus dari n elemen terkecil dalam salinan adalah elemen terbesar dalam orisinal.
sumber
-array
Seperti @Kanmani mengisyaratkan, implementasi implementasi yang lebih mudah dapat digunakan
numpy.flip
, seperti pada yang berikut:Dengan menggunakan pola pengunjung daripada fungsi anggota, lebih mudah untuk membaca urutan operasi.
sumber
Dengan contoh Anda:
Dapatkan indeks n nilai maksimal:
Sortir dalam urutan menurun:
Dapatkan hasil (untuk n = 4):
sumber
Cara lain adalah dengan menggunakan hanya '-' dalam argumen untuk argsort seperti pada: "df [np.argsort (-df [:, 0])]", asalkan df adalah kerangka data dan Anda ingin mengurutkannya dengan yang pertama kolom (diwakili oleh nomor kolom '0'). Ubah nama kolom yang sesuai. Tentu saja, kolom harus berupa angka.
sumber