matlab - 如何对包含分组数据的矩阵进行行排序

标签 matlab sorting matrix grouping split-apply-combine

在矩阵A中,每一列代表一个输出变量,每一行代表一个读数(总共6行)。每个输出都有一定的子组大小(3 行组)。我需要 A 的元素在每个子组内按垂直方向排序。

A = [ 1 7 4; 4 9 3; 8 5 7; 2 9 1; 7 4 4; 8 1 3];
% consecutive 3 rows is one subgroup, within which sorting is required.
B = [1 5 3; 4 7 4; 8 9 7; 2 1 1; 7 4 3; 8 9 4]; % the expected result.

我正在考虑类似 B = splitapply(@sort,A,2) 的东西,但是 splitapply 不能这样调用。如何才能得到想要的结果?

请注意,实际矩阵包含 8 列和 300 行。上面演示了一个示例。

最佳答案

最简单的解决方案是 reshape 数据、排序,然后排列它:

rps = 3; % rows per subgroup 
B = permute(sort(reshape(A.',rps,size(A,2),[]),2),[2 1 3]);

上面的结果是一个 3x3x2 的数组,在我看来,它更容易使用,但是如果您想要像示例中那样的输出,您可以执行以下操作:

B = reshape(permute(sort(reshape(A.',rps,size(A,2),[]),2),[2 3 1]),size(A));

或者,您认为 splitapply 在这里很有用,这是正确的,但它需要更多的工作。

此命令适用于示例数据,也应该适用于您的完整数据集:

b = cell2mat( splitapply( @(x){sort(x,2).'}, A.', repelem( 1:size(A,1)/rps, rps ) ).' );

我将解释它的作用:

  • repelem( 1:size(A,1)/rps, rps ) 返回组的行向量。组的数量是行总数除以组大小。 (为了更好地衡量,应该断言它是可以整除的,没有余数)。
  • splitapply( @(x){sort(x,2).'}, ... 因为 splitapply 必须为每个组返回一个标量对象,需要告诉它输出是一个单元格,以便它可以返回一个矩阵。(这可能不是最好的解释,但如果您尝试在没有单元格输出的情况下运行它,您将收到以下错误:

    The function 'sort' returned a non-scalar value when applied to the 1st group of data.
    
    To compute nonscalar values for each group, create an anonymous function to return each value in a scalar cell:
    
        @(x1){sort(x1)}
    
  • 我执行了几次转置操作,因为这是 splitapply 所期望的。

  • 我使用 cell2mat 将输出单元格转换回数值数组。

关于matlab - 如何对包含分组数据的矩阵进行行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50482908/

相关文章:

c++ - 你如何用特征向量制作矩阵?

c++ - 如何在 CUDA 中实现子矩阵的接口(interface)?

matlab - 在 Matlab 中播放 mp3

matlab - 选择用于图像识别的神经网络变量

java - CodeChef TurboSort(使用 int 与 Integer 排序)

c - 弄清楚三元运算符级联的功能?

matlab - 内部矩阵维度必须一致?

arrays - 在不扭曲数据的情况下正确 reshape matlab中的多维N-D数组

matlab - 在不可见属性上同步多个轴

list - 基于第二个属性的Scala排序列表,然后是第一个