【问题标题】:Get the indices of the n largest elements in a matrix获取矩阵中 n 个最大元素的索引
【发布时间】:2011-02-11 03:47:46
【问题描述】:

假设我有以下矩阵:

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

我想要前 5 个元素的索引(在本例中为 32、13、12、11、10)。在 MATLAB 中最简洁的方法是什么?

【问题讨论】:

  • 一个澄清:你想如何处理重复的元素?例如,如果数字 32 出现 7 次,您是要获取所有 7 个的索引,还是只获取其中的 5 个,或者只获取其中 1 个,然后获取接下来 4 个最大元素的索引?
  • @Eric Leschinski 请不要在标题中添加标签,这不是必需的,社区通常不鼓励这样做(参见this meta post for the official answer on this topic)

标签: matlab matrix


【解决方案1】:

有几种方法可以做到这一点,具体取决于您要如何处理重复值。这是一个使用 sort 查找 5 个最大值(可能包括重复值)的索引的解决方案:

[~, 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 个最大的 unique 值,然后找到与这些值相等的 所有 元素(如果存在重复值,则可能超过 5 个),使用unique 和ismember:

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

【讨论】:

  • 其实gnovice提出的最后一步是不需要做的。 sort 的第二个输出是排序的标签列表。因此,这些选定值的索引由排序中的相应标签给出。如果您希望根据一对下标获得索引,请调用 ind2sub。
  • @woodchips:很好。正如您评论的那样,我正在更改它,并添加另一个选项以不同的方式处理重复值。
  • 这种方法对于小矩阵来说可能是最干净的,但对于大矩阵来说显然是次优的,因为像 O(N*log(N)) 这样的排序比例,而“非 Matlab 方式”会缩放像 O(N)。
  • UNIQUE 已经返回排序值和矢量格式,所以第一行中的 unique(A) 应该可以工作。
  • 感谢您对这个问题的简洁准确的回答。你帮了我很多忙!
【解决方案2】:

如果您有一个相当大的数组并且只想要其中的几个元素。这将是我的解决方案。

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

我认为它应该比排序解决方案更快且对 RAM 的需求更少。

【讨论】:

  • 这仅在 n 个最大元素大于 0 时才有效。否则将 0 替换为 min(Arraycopy, ...)。
【解决方案3】:

您也可以在 matlabcentral 上找到有关 matlab 问题的好答案。在搜索相同的东西时,我在那里找到了一个很好的 mex 实现。

这是由 Bruno Luong 使用 C-MEX 实现的部分快速排序算法完成的。复杂度为 O(n + k.log(k)),其中 n 是数组的大小,k 是要选择的元素数。对于大尺寸输入,它比 SORT 或多次调用 MIN/MAX 更快。支持多维能力

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

【讨论】:

    【解决方案4】:

    在 MATLAB ≥ R2017b 中,您可以将maxk 用于此特定目的。

    [maxvalues, ind] = maxk(A(:), 5);
    

    【讨论】:

    • 不错!看起来它与我的答案中的第一个解决方案具有相同的行为(即输出可以包含重复值)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    • 2015-06-24
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    相关资源
    最近更新 更多