Fondamentalmente devi fare un argsort
, quale implementazione ti serve se vuoi usare librerie esterne (es. NumPy) o se vuoi rimanere pure-Python senza dipendenze.
La domanda che devi porti è: vuoi il
- indici che ordinerebbero la matrice / lista
- indici che gli elementi avrebbero nella matrice / lista ordinata
Sfortunatamente l'esempio nella domanda non chiarisce ciò che si desidera perché entrambi daranno lo stesso risultato:
>>> arr = np.array([1, 2, 3, 100, 5])
>>> np.argsort(np.argsort(arr))
array([0, 1, 2, 4, 3], dtype=int64)
>>> np.argsort(arr)
array([0, 1, 2, 4, 3], dtype=int64)
Scelta argsort
dell'implementazione
Se hai NumPy a tua disposizione, puoi semplicemente utilizzare la funzione numpy.argsort
o il metodo numpy.ndarray.argsort
.
Un'implementazione senza NumPy è già stata menzionata in alcune altre risposte, quindi ricapitolerò la soluzione più veloce in base alla risposta del benchmark qui
def argsort(l):
return sorted(range(len(l)), key=l.__getitem__)
Ottenere gli indici che ordinerebbero la matrice / lista
Per ottenere gli indici che ordinerebbero l'array / list, puoi semplicemente chiamare argsort
l'array o l'elenco. Sto usando le versioni di NumPy qui, ma l'implementazione di Python dovrebbe dare gli stessi risultati
>>> arr = np.array([3, 1, 2, 4])
>>> np.argsort(arr)
array([1, 2, 0, 3], dtype=int64)
Il risultato contiene gli indici necessari per ottenere l'array ordinato.
Poiché la matrice ordinata sarebbe [1, 2, 3, 4]
la matrice argsorted contiene gli indici di questi elementi nell'originale.
- Il valore più piccolo è
1
ed è all'indice 1
dell'originale, quindi il primo elemento del risultato è 1
.
- L'
2
indice è 2
nell'originale, quindi il secondo elemento del risultato è 2
.
- L'
3
indice è 0
nell'originale quindi il terzo elemento del risultato è 0
.
- Il valore più grande
4
ed è all'indice 3
dell'originale, quindi l'ultimo elemento del risultato è 3
.
Ottenere gli indici che gli elementi avrebbero nella matrice / lista ordinata
In questo caso dovrai applicare argsort
due volte :
>>> arr = np.array([3, 1, 2, 4])
>>> np.argsort(np.argsort(arr))
array([2, 0, 1, 3], dtype=int64)
In questo caso :
- il primo elemento dell'originale è
3
, che è il terzo valore più grande, quindi dovrebbe essere indicizzato 2
nella matrice / lista ordinata, quindi il primo elemento è 2
.
- il secondo elemento dell'originale è
1
, che è il valore più piccolo, quindi dovrebbe essere indicizzato 0
nella matrice / lista ordinata, quindi il secondo elemento è 0
.
- il terzo elemento dell'originale è
2
, che è il secondo valore più piccolo, quindi avrebbe l'indice 1
nella matrice / lista ordinata, quindi il terzo elemento è 1
.
- il quarto elemento dell'originale è
4
il valore più grande, quindi dovrebbe essere indicizzato 3
nella matrice / lista ordinata, quindi l'ultimo è 3
.