Отсортируйте матрицу с другой матрицей

Предположим, что у меня есть матрица A и я сортирую строки этой матрицы. Как я копирую то же упорядочивание на матрице B (тот же размер, конечно)?

Например.

A = rand(3,4);
[val ind] = sort(A,2);
B = rand(3,4);
%// Reorder the elements of B according to the reordering of A

Это является лучшим, я придумал

m = size(A,1);
B = B(bsxfun(@plus,(ind-1)*m,(1:m)'));

Из любопытства, каких-либо альтернатив?

Обновление: отличное решение Jonas, представленное на 2008a (XP):

n = n

0.048524       1.4632       1.4791        1.195       1.0662        1.108       1.0082      0.96335      0.93155      0.90532      0.88976

n = 2 м

0.63202       1.3029       1.1112       1.0501      0.94703      0.92847      0.90411       0.8849       0.8667      0.92098      0.85569

Это просто идет, чтобы показать, что циклы не являются анафемой на программистов MATLAB больше благодаря JITA (возможно).

21
задан Community 23 May 2017 в 12:34
поделиться

2 ответа

Несколько более ясный способ сделать это - использовать цикл

A = rand(3,4);
B = rand(3,4);
[sortedA,ind] = sort(A,2);

for r = 1:size(A,1)
   B(r,:) = B(r,ind(r,:));
end

Интересно, что версия цикла работает быстрее для маленьких (<12 строк) и больших (> ~ 700 строк) квадратных массивов (r2010a, OS X). Чем больше столбцов относительно строк, тем лучше работает цикл.

Вот код, который я быстро взломал для тестирования:

siz = 10:100:1010;
tt = zeros(100,2,length(siz));

for s = siz
    for k = 1:100

        A = rand(s,1*s);
        B = rand(s,1*s);
        [sortedA,ind] = sort(A,2);

        tic;
        for r = 1:size(A,1)
            B(r,:) = B(r,ind(r,:));
        end,tt(k,1,s==siz) = toc;

        tic;
        m = size(A,1);
        B = B(bsxfun(@plus,(ind-1)*m,(1:m).'));
        tt(k,2,s==siz) = toc;

    end
end

m = squeeze(mean(tt,1));

m(1,:)./m(2,:)

Для квадратных массивов

ans =

    0.7149    2.1508    1.2203    1.4684    1.2339    1.1855    1.0212    1.0201    0.8770       0.8584    0.8405

Для вдвое большего количества столбцов, чем строк (такое же количество строк)

ans =

    0.8431    1.2874    1.3550    1.1311    0.9979    0.9921    0.8263    0.7697    0.6856    0.7004    0.7314
17
ответ дан 29 November 2019 в 21:49
поделиться

Sort () возвращает индекс по измерению, по которому вы выполняли сортировку. Вы можете явно создать индексы для других измерений, чтобы строки оставались стабильными, а затем использовать линейную индексацию для переупорядочения всего массива.

A = rand(3,4);
B = A; %// Start with same values so we can programmatically check result

[A2 ix2] = sort(A,2);
%// ix2 is the index along dimension 2, and we want dimension 1 to remain unchanged
ix1 = repmat([1:size(A,1)]', [1 size(A,2)]); %//'
%// Convert to linear index equivalent of the reordering of the sort() call
ix = sub2ind(size(A), ix1, ix2) 
%// And apply it
B2 = B(ix)
ok = isequal(A2, B2) %// confirm reordering
5
ответ дан 29 November 2019 в 21:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: