NumPy - menuruni array arg-sort stabil dari tipe dt apa pun

Oct 07 2020

Np.argsort NumPy mampu melakukan penyortiran stabil melalui kind = 'stable'argumen yang lewat .

Juga np.argsorttidak mendukung urutan mundur (menurun).

Jika diperlukan perilaku yang tidak stabil, urutan menurun dapat dengan mudah dimodelkan desc_ix = np.argsort(a)[::-1].

Saya mencari solusi yang efisien / mudah untuk deretan NumPy yang menurun-stabil-jenis yang asebanding dtype. Lihat arti saya tentang "stabilitas" di paragraf terakhir.

Untuk kasus ketika dtypeada numerik maka stabil descending arg-sorting dapat dengan mudah dilakukan melalui pengurutan versi larik yang dinegasikan:

print(np.argsort(-np.array([1, 2, 2, 3, 3, 3]), kind = 'stable'))
# prints: array([3, 4, 5, 1, 2, 0], dtype=int64)

Tapi saya perlu mendukung semua yang sebanding dtypetermasuk np.str_dan np.object_.

Hanya untuk klarifikasi - mungkin untuk urutan menurun, makna klasik stableberarti bahwa elemen yang sama disebutkan dari kanan ke kiri. Jika demikian maka dalam pertanyaan saya artinya stable + descendingadalah sesuatu yang berbeda - rentang elemen yang sama harus dihitung dari kiri ke kanan, sementara rentang yang sama antara satu sama lain diurutkan dalam urutan menurun. Yaitu perilaku yang sama harus dicapai seperti pada kode terakhir di atas. Yaitu saya ingin stabilitas dalam arti yang sama seperti yang dicapai Python dalam kode berikutnya:

print([e[0] for e in sorted(enumerate([1,2,2,3,3,3]), key = lambda e: e[1], reverse = True)])
# prints: [3, 4, 5, 1, 2, 0]

Jawaban

2 jdehesa Oct 07 2020 at 18:30

Saya pikir rumus ini harus bekerja:

import numpy as np
a = np.array([1, 2, 2, 3, 3, 3])
s = len(a) - 1 - np.argsort(a[::-1], kind='stable')[::-1]
print(s)
# [3 4 5 1 2 0]
1 Divakar Oct 07 2020 at 14:04

Kita dapat memanfaatkan np.unique(..., return_inverse=True)-

u,tags = np.unique(a, return_inverse=True)
out = np.argsort(-tags, kind='stable')
Arty Oct 07 2020 at 13:41

Salah satu solusi paling sederhana adalah melalui pemetaan elemen unik yang diurutkan dari dtypebilangan bulat menaik dan kemudian penyortiran arg menaik yang stabil dari bilangan bulat yang dinegasikan.

Cobalah secara online!

import numpy as np
a = np.array(['a', 'b', 'b', 'c', 'c', 'c'])
u = np.unique(a)
i = np.searchsorted(u, a)
desc_ix = np.argsort(-i, kind = 'stable')
print(desc_ix)
# prints [3 4 5 1 2 0]