Как отсортировать по матрице строку, содержащую данные подгруппы

В матрице 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 строк. Пример демонстрируется выше.

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