Как отсортировать по матрице строку, содержащую данные подгруппы - PullRequest
0 голосов
/ 23 мая 2018

В матрице 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 Ответ

0 голосов
/ 23 мая 2018

Самым простым решением было бы изменить ваши данные, отсортировать, а затем переставить их:

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