2010-04-22 19 views
50

Supongamos que tengo la siguiente matriz:Obtener los índices de los n elementos más grandes en una matriz

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

Y quiero que los índices de los 5 primeros elementos (en este caso, 32, 13, 12, 11 , 10). ¿Cuál es la forma más limpia de hacer esto en MATLAB?

+2

Una aclaración: ¿Cómo le gustaría que tratar con elementos repetidos? Por ejemplo, si el número 32 apareció 7 veces, ¿le gustaría obtener índices para los 7, o solo cinco de ellos, o solo 1 de ellos y luego índices para los siguientes 4 elementos más grandes? – gnovice

+1

@Eric Leschinski Por favor, no agregue etiquetas a los títulos, no es necesario y, en general, desalentado por la comunidad (consulte [esta metapublicación para la respuesta oficial sobre este tema] (http://meta.stackexchange.com/a/ 5069/151385)) –

Respuesta

72

Hay varias formas de hacerlo, dependiendo de cómo quiera manejar los valores repetidos. He aquí una solución que encuentra índices de los 5 valores más grandes (que podrían incluir valores repetidos):

[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 

he aquí una solución que encuentra los 5 más grandes valores únicos, a continuación, busca todos los elementos iguales a los valores:

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

En realidad, no hay necesidad de hacer el último paso planteado por gnovice. El segundo resultado del género es una lista de etiquetas para el género. Entonces el índice de esos valores seleccionados viene dado por las etiquetas correspondientes del género. Si desea el índice en términos de un par de subíndices, llame a ind2sub. –

+0

@woodchips: Buena captura. Estuve en el proceso de cambiarlo como me comentó, y agregué otra opción para tratar los valores repetidos de una manera diferente. – gnovice

+3

Este método es probablemente el más limpio para matrices pequeñas, pero claramente subóptimo para matrices grandes ya que escalas de clasificación como O (N * log (N)) mientras lo hace el "modo no Matlab" se escalaría como O (N). – Adrien

15

Si tiene una matriz bastante grande y solo quiere algunos elementos de ella. Esta sería mi solución.

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

Creo que debería ser más rápido y con menor demanda de RAM que la solución de clasificación.

+2

Esto funciona solo si los n elementos más grandes son mayores que 0. De lo contrario, reemplace 0 por min (Arraycopy, ...). – Unapiedra

7

Puede encontrar buenas respuestas a las preguntas de matlab también en matlabcentral. Encontré una buena implementación de mex allí mientras buscaba lo mismo.

Es hecho por Bruno Luong utilizando un algoritmo parcial de ordenación rápida implementado con C-MEX. La complejidad es O (n + k.log (k)), donde n es el tamaño de la matriz, yk es la cantidad de elementos que se seleccionarán. Es más rápido que SORT o llamada múltiple de MIN/MAX para entradas de gran tamaño. capacidad multidimensional apoyado

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

Cuestiones relacionadas