Mengapa numpy memberikan hasil ini:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
ketika saya mengharapkannya melakukan ini:
[3 2 0 1]
Jelas pemahaman saya tentang fungsinya kurang.
Mengapa numpy memberikan hasil ini:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
ketika saya mengharapkannya melakukan ini:
[3 2 0 1]
Jelas pemahaman saya tentang fungsinya kurang.
Jawaban:
Menurut dokumentasi
Mengembalikan indeks yang akan mengurutkan larik.
2
adalah indeks 0.0
.3
adalah indeks 0.1
.1
adalah indeks 1.41
.0
adalah indeks 1.48
.a = x.argsort()
, cetak x[a]
, kita akan mendapatkanarray([ 0. , 0.1 , 1.41, 1.48])
[2, 3, 1, 0]
menunjukkan bahwa elemen terkecil ada pada indeks 2, terkecil berikutnya pada indeks 3, kemudian indeks 1, kemudian indeks 0.
Ada beberapa cara untuk mendapatkan hasil yang Anda cari:
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
Sebagai contoh,
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])
Ini memeriksa bahwa mereka semua menghasilkan hasil yang sama:
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))
%timeit
Tolok ukur IPython ini menyarankan agar array besar using_indexed_assignment
adalah yang tercepat:
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
Untuk array kecil, using_argsort_twice
mungkin lebih cepat:
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
Perhatikan juga bahwa stats.rankdata
memberi Anda lebih banyak kontrol atas cara menangani elemen dengan nilai yang sama.
argsort
mengembalikan indeks dari array yang diurutkan. Indeks dari indeks yang diurutkan adalah peringkat. Ini adalah panggilan kedua untuk argsort
kembali.
Sebagai dokumentasi mengatakan, argsort
:
Mengembalikan indeks yang akan mengurutkan larik.
Artinya elemen pertama dari argsort adalah indeks dari elemen yang harus diurutkan terlebih dahulu, elemen kedua adalah indeks dari elemen yang harus menjadi yang kedua, dll.
Apa yang Anda inginkan adalah urutan peringkat nilai, yang disediakan oleh scipy.stats.rankdata
. Perhatikan bahwa Anda perlu memikirkan tentang apa yang harus terjadi jika ada ikatan di peringkat.
numpy.argsort (a, axis = -1, kind = 'quicksort', order = None)
Mengembalikan indeks yang akan mengurutkan larik
Lakukan pengurutan tidak langsung di sepanjang sumbu yang diberikan menggunakan algoritme yang ditentukan oleh kata kunci kind. Ini mengembalikan array indeks dengan bentuk yang sama seperti data indeks di sepanjang sumbu yang diberikan dalam urutan yang diurutkan.
Pertimbangkan satu contoh di python, memiliki daftar nilai sebagai
listExample = [0 , 2, 2456, 2000, 5000, 0, 1]
Sekarang kami menggunakan fungsi argsort:
import numpy as np
list(np.argsort(listExample))
Outputnya akan
[0, 5, 6, 1, 3, 2, 4]
Ini adalah daftar indeks nilai di listExample jika Anda memetakan indeks ini ke nilai masing-masing maka kita akan mendapatkan hasilnya sebagai berikut:
[0, 0, 1, 2, 2000, 2456, 5000]
(Saya menemukan fungsi ini sangat berguna di banyak tempat, mis. Jika Anda ingin mengurutkan list / array tetapi tidak ingin menggunakan fungsi list.sort () (yaitu tanpa mengubah urutan nilai aktual dalam daftar) Anda dapat menggunakan ini fungsi.)
Untuk lebih jelasnya lihat tautan ini: https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.argsort.html
masukan:
impor numpy sebagai np
x = np.array ([1.48,1.41,0.0,0.1])
x.argsort (). argsort ()
keluaran:
larik ([3, 2, 0, 1])
Pertama, itu memerintahkan array. Kemudian buat sebuah array dengan indeks awal dari array tersebut.
np.argsort mengembalikan indeks dari array yang diurutkan yang diberikan oleh 'kind' (yang menentukan tipe algoritma pengurutan). Namun, ketika daftar digunakan dengan np.argmax, ia mengembalikan indeks elemen terbesar dalam daftar. Sementara, np.sort, mengurutkan array yang diberikan, list.
Hanya ingin secara langsung membandingkan pemahaman asli OP terhadap implementasi aktual dengan kode.
numpy.argsort
didefinisikan sedemikian rupa sehingga untuk array 1D:
x[x.argsort()] == numpy.sort(x) # this will be an array of True's
OP awalnya mengira bahwa itu didefinisikan sedemikian rupa untuk array 1D:
x == numpy.sort(x)[x.argsort()] # this will not be True
Catatan: Kode ini tidak berfungsi dalam kasus umum (hanya berfungsi untuk 1D), jawaban ini murni untuk tujuan ilustrasi.
x[x.argsort()]
belum tentu sama dengan np.sort(x)
. Bahkan, bentuknya belum tentu sama. Coba ini dengan array 2D. Ini hanya terjadi untuk bekerja dengan array 1D.
Ia mengembalikan indeks sesuai dengan indeks array yang diberikan [1.48,1.41,0.0,0.1]
, itu berarti:
0.0
adalah elemen pertama, dalam indeks [2].
0.1
adalah elemen kedua, dalam indeks [3].
1.41
adalah elemen ketiga, dalam indeks [1].
1.48
adalah elemen keempat, dalam indeks [0]. Keluaran:
[2,3,1,0]
[3 2 0 1]
menjadi jawaban yang benar?