2

在 matrixA中,每一列代表一个输出变量,每一行代表一个读数(共 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 行。上面演示了一个示例。

4

1 回答 1

4

最简单的解决方案是重塑您的数据,排序,然后排列它:

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将输出单元格转换回数值数组。
于 2018-05-23T08:13:20.160 回答