Сортировать каждый диапазон вектора - PullRequest
0 голосов
/ 05 сентября 2018

Дан следующий вектор:

5 4 1 2 3 1 4 5 3 2 3 2 1 5 4
_________ _________ _________

Я хочу применить сортировку к каждому 5 элементам вектора. Таким образом, выход будет:

1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 
_________ _________ _________

Как добиться этого без циклов в MATLAB?

P.S. Я также хочу извлечь индексы сортировки, чтобы применить их к другому вектору.

1 Ответ

0 голосов
/ 05 сентября 2018

Если вы хотите избежать петель, вы можете использовать комбинацию reshape и sort для достижения того, что вы хотите:

b = [5 4 1 2 3 1 4 5 3 2 3 2 1 5 4];
b2 = reshape(b, [5 3]);           % Reshape your array to be a [5x3] matrix
b2_new = sort(b2, 1);             % Sort each column of your matrix seperately
b_new = reshape(b2_new, size(b)); % Reshape the outcome back to the original dimensions

Или все в одной строке:

b_new = reshape(sort(reshape(b, [5 3]), 1), size(b));

Вам, конечно, придется изменить номера 5 и 3, чтобы они соответствовали вашей проблеме. Важно убедиться, что первое значение, которое вы задаете для команды изменения формы (в данном случае 5), равно длине субвекторов, которые вы хотите отсортировать, так как Matlab - главный столбец.

Изменить:

Если вы хотите отсортировать один конкретный вектор, а затем применить то же переупорядочение к другим векторам, вы можете использовать необязательный второй выходной аргумент функции sort. Работа с теми же векторами, что и выше:

b = [5 4 1 2 3 1 4 5 3 2 3 2 1 5 4];
b2 = reshape(b, [5 3]);

выходы:

b2 = 5 1 3
     4 4 2
     1 5 1
     2 3 5
     3 2 4

Скажем, вы хотите отсортировать первый столбец и применить то же переупорядочение ко второму и третьему, вы делаете:

[~,idx] = sort( b2(:,1) );   % Sorts the first column of b2, and stores the index map in 'idx'

Это даст idx = [3 4 5 2 1]. Теперь вы можете использовать эти индексы для сортировки всех столбцов:

b2_new = b2(idx,:);
b2_new =
     1     5     1
     2     3     5
     3     2     4
     4     4     2
     5     1     3

И, наконец, вы можете использовать reshape вернуться к исходным размерам:

b_new = reshape(b2_new, size(b));

Редактировать 2:

Если вы хотите сохранить переупорядочение b в целом и применить его к новому вектору c, нам нужно стать немного более креативным. Ниже приведен один из подходов:

b = [5 4 1 2 3 1 4 5 3 2 3 2 1 5 4];
b2, = reshape(b, [5 3]);

% Sort each column of your matrix seperately, and store the index map
[~,idx] = sort(b2, 1);

% Alter the index map, such that the indices are now linear indices:
idx = idx + (0:size(idx,2)-1)*size(idx,1);

% Reshape the index map to the original dimensions of b:
idx = reshape(idx, size(b));

% Now sort any array you want using this index map as follows:
b_new = b(idx);
c_new = c(idx);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...