假设我有一个矩阵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
Run Code Online (Sandbox Code Playgroud)
这是我提出的最好的
m = size(A,1);
B = B(bsxfun(@plus,(ind-1)*m,(1:m)'));
Run Code Online (Sandbox Code Playgroud)
出于好奇,还有其他选择吗?
0.048524 1.4632 1.4791 1.195 1.0662 1.108 1.0082 0.96335 0.93155 0.90532 0.88976
Run Code Online (Sandbox Code Playgroud)
0.63202 1.3029 1.1112 1.0501 0.94703 0.92847 0.90411 0.8849 0.8667 0.92098 0.85569
Run Code Online (Sandbox Code Playgroud)
它只是表明,由于JITA(或许),循环不再是MATLAB程序员的诅咒.
Jon*_*nas 17
更简单的方法是使用循环
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
Run Code Online (Sandbox Code Playgroud)
有趣的是,对于小型(<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,:)
Run Code Online (Sandbox Code Playgroud)
对于方阵
ans =
0.7149 2.1508 1.2203 1.4684 1.2339 1.1855 1.0212 1.0201 0.8770 0.8584 0.8405
Run Code Online (Sandbox Code Playgroud)
列数是行的两倍(行数相同)
ans =
0.8431 1.2874 1.3550 1.1311 0.9979 0.9921 0.8263 0.7697 0.6856 0.7004 0.7314
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)