Самым простым решением было бы изменить ваши данные, отсортировать, а затем переставить их:
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
, чтобы преобразовать выходные ячейки обратно в числовой массив.