Bir diziyi reddederseniz, en düşük öğeler en yüksek öğeler olur veya tersi de geçerlidir. Bu nedenle, en n
yüksek elementlerin endeksleri :
(-avgDists).argsort()[:n]
Bu konuda akıl yürütmenin bir başka yolu, yorumlarda belirtildiği gibi , büyük öğelerin argsort'ta son geldiğini gözlemlemektir. Böylece, en n
yüksek öğeleri bulmak için argsort'un kuyruğundan okuyabilirsiniz :
avgDists.argsort()[::-1][:n]
Her iki yöntem de zaman karmaşıklığında O (n log n) şeklindedir , çünkü argsort
çağrı burada baskın terimdir. Ancak ikinci yaklaşımın güzel bir avantajı vardır: dizinin O (n) negatifliğini O (1) dilimi ile değiştirir. Döngülerin içindeki küçük dizilerle çalışıyorsanız, bu olumsuzlamadan kaçınmaktan bazı performans kazanımları elde edebilirsiniz ve büyük dizilerle çalışıyorsanız, olumsuzlama tüm dizinin bir kopyasını oluşturduğundan bellek kullanımından tasarruf edebilirsiniz.
Bu yöntemlerin her zaman eşdeğer sonuçlar vermediğini unutmayın: argsort
örneğin, anahtar kelime bağımsız değişkenini geçerek kararlı bir sıralama uygulaması istenirse kind='mergesort'
, ilk strateji sıralama kararlılığını koruyacaktır, ancak ikinci strateji istikrarı bozacaktır (yani eşit konumlar öğeler ters alacak).
Örnek zamanlamalar:
100 şamandıra ve uzunluk 30 kuyruktan oluşan küçük bir dizi kullanarak, görüntüleme yöntemi yaklaşık% 15 daha hızlıydı
>>> 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)
Daha büyük diziler için argsort baskındır ve önemli bir zamanlama farkı yoktur
>>> 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)
Aşağıdaki nedim'den gelen yorumun yanlış olduğunu lütfen unutmayın . Bu işlemlerin her ikisi de dizinin yalnızca farklı bir görünümünden geçiyor ve gerçekte veri kopyalamıyor olduğundan, tersine dönmeden önce veya sonra kesip kesmemek verimlilikte bir fark yaratmıyor.
ids = np.array(avgDists).argsort()[-n:]
?