Получить индексы n самых больших элементов в матрице

50

Предположим, что у меня есть следующая матрица:

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

И мне нужны индексы из 5 лучших элементов (в данном случае 32, 13, 12, 11, 10). Каков самый чистый способ сделать это в MATLAB?

  • 2
    Одно уточнение: как бы вы хотели иметь дело с повторяющимися элементами? Например, если число 32 появилось 7 раз, вы хотите получить индексы для всех 7, или только пять из них, или только 1 из них, а затем индексы для следующих 4 самых больших элементов?
  • 1
    @Eric Leschinski Пожалуйста, не добавляйте теги к заголовкам, это необязательно и обычно не приветствуется сообществом ( официальный ответ по этой теме см. В этом мета-сообщении )
Теги:
matrix

3 ответа

68
Лучший ответ

Есть несколько способов сделать это в зависимости от того, как вы хотите иметь дело с повторяющимися значениями. Здесь найдено решение, которое находит индексы для 5 самых больших значений (которые могут включать повторяющиеся значения):

[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

Здесь решение, которое находит 5 самых больших уникальных значений, затем находит все элементы равными этим значениям:

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
    На самом деле, нет необходимости делать последний шаг, представленный gnovice. Второй результат сортировки - это список тегов для сортировки. Таким образом, индекс этих выбранных значений дается соответствующими тегами из сортировки. Если вы хотите индекс для пары индексов, вызовите ind2sub.
  • 0
    @ Woodchips: Хороший улов. Я находился в процессе его изменения, как вы прокомментировали, а также добавил еще одну опцию для обработки повторяющихся значений другим способом.
Показать ещё 4 комментария
15

Если у вас есть довольно большой массив и вам нужно только несколько элементов. Это было бы моим решением.

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

Я думаю, что это должно быть быстрее и меньше оперативной памяти, чем решение сортировки.

  • 2
    Это работает, только если n самых больших элементов больше 0. В противном случае замените 0 на min (Arraycopy, ...).
7

Вы можете найти хорошие ответы на вопросы matlab также на matlabcentral. Я нашел хорошую реализацию mex там, ища то же самое.

Это выполняется Бруно Луонгом, используя алгоритм частичной быстрой сортировки, реализованный с помощью C-MEX. Сложность - O (n + k.log(k)), где n - размер массива, а k - количество элементов, которые нужно выбрать. Это быстрее, чем SORT или множественный вызов MIN/MAX для ввода большого размера. Поддержка многомерных возможностей

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню