在矩阵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/