2010-04-22 15 views
50

Supponiamo Ho la seguente matrice:Ottenere gli indici degli elementi n più grande in una matrice

01 02 03 06 
03 05 07 02 
13 10 11 12 
32 01 08 03 

E voglio gli indici dei primi 5 elementi (in questo caso, 32, 13, 12, 11 10). Qual è il modo più pulito per farlo in MATLAB?

+2

Una precisazione: come si vorrebbe fare con elementi ripetuti? Ad esempio, se il numero 32 è apparso 7 volte, vorresti ottenere indici per tutti i 7, o solo cinque di essi, o solo 1 di essi e quindi indici per i successivi 4 elementi più grandi? – gnovice

+1

@Eric Leschinski Si prega di non aggiungere tag ai titoli, non è necessario e generalmente scoraggiato dalla comunità (vedi [questo meta post per la risposta ufficiale su questo argomento] (http://meta.stackexchange.com/a/ 5069/151385)) –

risposta

72

Ci sono un paio di modi in cui puoi farlo a seconda di come vuoi gestire i valori ripetuti. Ecco una soluzione che trova indici per i 5 valori più grandi (che potrebbe includere valori ripetuti):

[sortedValues,sortIndex] = sort(A(:),'descend'); %# Sort the values in 
                %# descending order 
maxIndex = sortIndex(1:5); %# Get a linear index into A of the 5 largest values 

Ecco una soluzione che trova 5 maggiori uniche valori, poi trova tutti gli elementi uguali a quei valori:

sortedValues = unique(A(:));   %# Unique sorted values 
maxValues = sortedValues(end-4:end); %# Get the 5 largest values 
maxIndex = ismember(A,maxValues);  %# Get a logical index of all values 
             %# equal to the 5 largest values 
+1

In realtà, non è necessario eseguire l'ultimo passaggio proposto da gnovice. Il secondo output di sort è un elenco di tag per l'ordinamento. Quindi l'indice di quei valori selezionati è dato dai tag corrispondenti dall'ordinamento. Se desideri l'indice in termini di una coppia di pedici, chiama ind2sub. –

+0

@woodchips: buona presa. Stavo cambiando mentre commentavi, così come aggiungendo un'altra opzione per gestire i valori ripetuti in un modo diverso. – gnovice

+3

Questo metodo è probabilmente il più pulito per le matrici piccole, ma chiaramente sub-ottimale per le matrici di grandi dimensioni poiché l'ordinamento di scale come O (N * log (N)) mentre lo fa il "modo non Matlab" si ridimensiona come O (N). – Adrien

15

Se si dispone di un array piuttosto grande e desidera solo alcuni elementi da esso. Questa sarebbe la mia soluzione.

Arraycopy = Array; 
for j = 1:n 
    [a, Index(j)] = max(Arraycopy); 
    Arraycopy(Index(j)) = -inf; 
end 
maximumValues = Array(Index); 

Penso che dovrebbe essere più veloce e meno impegnativo di RAM rispetto alla soluzione di ordinamento.

+2

Funziona solo se i n elementi più grandi sono maggiori di 0. Altrimenti sostituisci 0 per min (Arraycopy, ...). – Unapiedra

7

È possibile trovare buone risposte alle domande MATLAB anche su MATLABCENTRALE. Ho trovato una buona implementazione del mess durante la ricerca della stessa cosa.

Viene eseguito da Bruno Luong utilizzando un algoritmo di ordinamento rapido parziale implementato con C-MEX. La complessità è O (n + k.log (k)), dove n è la dimensione dell'array, e k è il numero di elementi da selezionare. È più veloce di SORT o chiamata multipla di MIN/MAX per ingressi di grandi dimensioni. capacità Multidimensionale supportato

http://www.mathworks.com/matlabcentral/fileexchange/23576-minmax-selection

Problemi correlati