【问题标题】:How to rowwise-sort a matrix containing subgrouped data如何对包含子分组数据的矩阵进行逐行排序
【发布时间】:2018-11-02 02:53:59
【问题描述】:

在矩阵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 行。上面展示了一个例子。

【问题讨论】:

  • 请显示预期的输出。
  • 您的意思是在每个子组中对A每一列 进行排序,对吧?
  • @Luis- 你是对的

标签: matlab sorting matrix grouping split-apply-combine


【解决方案1】:

最简单的解决方案是重塑数据,排序,然后置换:

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 将输出单元格转换回数值数组。

【讨论】:

  • @user9003011 完成。当我最初写这个答案时,rps 定义确实是第一行代码,但后来我添加了另一种方式,它变得混乱了。
猜你喜欢
  • 1970-01-01
  • 2016-04-18
  • 2017-03-25
  • 1970-01-01
  • 2020-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-03
相关资源
最近更新 更多