如何按行对包含子分组数据的矩阵进行排序
How to rowwise-sort a matrix containing subgrouped data
在矩阵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 行。上面演示了一个例子。
最简单的解决方案是重塑数据、排序,然后排列:
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 )
returns 组的行向量。组的数量是总行数除以组大小。 (为了更好的衡量,应该断言这是可以整除的,没有余数)。
splitapply( @(x){sort(x,2).'}, ...
因为 splitapply
必须 return 每组一个标量对象,所以需要告知输出是一个单元格,以便它可以 return一个矩阵。 (这可能不是最好的解释,但如果您尝试 运行 它 w/o 单元格输出,您将收到以下错误:
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
将输出单元格转换回数值数组。
在矩阵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 行。上面演示了一个例子。
最简单的解决方案是重塑数据、排序,然后排列:
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 )
returns 组的行向量。组的数量是总行数除以组大小。 (为了更好的衡量,应该断言这是可以整除的,没有余数)。splitapply( @(x){sort(x,2).'}, ...
因为splitapply
必须 return 每组一个标量对象,所以需要告知输出是一个单元格,以便它可以 return一个矩阵。 (这可能不是最好的解释,但如果您尝试 运行 它 w/o 单元格输出,您将收到以下错误: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
将输出单元格转换回数值数组。