【问题标题】:How to sort rows of a matrix based on frequency of the elements of one column?如何根据一列元素的频率对矩阵的行进行排序?
【发布时间】:2015-08-07 09:55:20
【问题描述】:

我尝试在 Matlab 中使用 sortrows 函数。有没有什么方法可以使用这个函数或任何想法根据矩阵列元素的频率对矩阵的行进行排序。

举个例子:我有这个矩阵

matrix = [1 3 1;
          1 4 2;
          2 5 4;
          3 2 3; 
          5 5 4; 
          5 3 3; 
          4 3 2; 
          4 2 3; 
          3 6 4; 
          2 4 3];

我想得到类似的东西:

sorted_based_on_3rd_col = [2 4 3;
                           3 2 3;
                           4 2 3;
                           5 3 3;
                           2 5 4;
                           3 6 4;
                           5 5 4;
                           1 4 2;
                           4 3 2;
                           1 3 1]

根据第三列最频繁的元素排序。 感谢您的帮助!

【问题讨论】:

  • 同一个号码的顺序怎么选? sorted_based_on_3rd_col 的前 4 件商品是如何订购的?
  • @AnderBiguri 实际上这个输出没有差异。我想我以后可以按第一列或第二列对它们进行排序。对吗?
  • 你不能告诉算法“然后用这个做任何你想做的事”。选择您希望他们订购的方式!
  • 可能类似于accumarray,然后构造第四列,其中包含对 accumarray 的查找,按第四列排序,然后删除第四列。 (抱歉没有代码。)
  • @AnderBiguri 好的。前 4 项应根据第一列升序排序。

标签: arrays matlab sorting matrix


【解决方案1】:

这是一种方式:

x = matrix(:,3);
[c,b] = histc(x,unique(x))
[~,idx] = sort(c(b),'descend')
out = matrix(idx,:)

【讨论】:

  • histc 的第二个输出——好想!
  • @thewaywewalk 非常感谢您的回答。这是完全正确和有用的,但我只有一个选择最佳答案。
【解决方案2】:

如果你不关心频率相等的元素的顺序,可以这样做:

>> freq = accumarray(matrix(:,3), 1);
>> [~, ind] = sort(freq(matrix(:, 3)), 1, 'descend');  % index that sorts matrix
>> matrix(ind, :)  % reshuffle matrix to sort

ans =

     3     2     3
     5     3     3
     4     2     3
     2     4     3
     2     5     4
     5     5     4
     3     6     4
     1     4     2
     4     3     2
     1     3     1

如果您确实关心,则需要先对矩阵进行预排序。由于 matlab 的排序是stable,这将保留第二次排序中相等的项目的顺序。

>> matrix = sortrows(matrix, 1)

matrix =

     1     3     1
     1     4     2
     2     5     4
     2     4     3
     3     2     3
     3     6     4
     4     3     2
     4     2     3
     5     5     4
     5     3     3

>> freq = accumarray(matrix(:,3),1);
>> [~, ind] = sort(freq(matrix(:,3)), 1, 'descend');
>> matrix(ind, :)

ans =

     2     4     3
     3     2     3
     4     2     3
     5     3     3
     2     5     4
     3     6     4
     5     5     4
     1     4     2
     4     3     2
     1     3     1

【讨论】:

    最近更新 更多