矢量化方法
这假定A 是输入矩阵。
[m,n] = size(A); %// size of input matrix
[~,id] = sort(A(:,2:2:end),1); %// sorted IDs
%// Use id to get linear indices of all elements based on asked sorting criteria
%// and index into A for the final output
Aout = A(bsxfun(@plus,reshape(repmat(permute(id,[1 3 2]),1,2),m,n),[0:n-1]*m));
最后一行可以替换为以下代码,这似乎为小数据大小提供了边际运行时改进 -
Aout = A(bsxfun(@plus,reshape(repmat(id,2,1),m,n),[0:n-1]*m));
基准测试
本部分将提议的矢量化方法与@Daniel's answer 和late addition by @Luis 中列出的基于循环的方法进行基准测试。
基准代码
%// Random huge input array
A = rand(10000);
disp('---------------------------------------- With vectorized approach')
tic
[m,n] = size(A); %// size of input matrix
[~,id] = sort(A(:,2:2:end),1); %// sorted IDs
%// Use id to get linear indices of all elements based on asked sorting criteria
Aout = A(bsxfun(@plus,reshape(repmat(permute(id,[1 3 2]),1,2),m,n),[0:n-1]*m));
toc
clear Aout m n id
disp('---------------------------------------- With loop based approach')
tic
Aout2 = zeros(size(A));
for idx=1:2:size(A,2)
Aout2(:,idx:idx+1)=sortrows(A(:,idx:idx+1),2);
end
toc
clear Aout2 idx
disp('---------------------------------------- With Luis Vectorized approach')
tic
[m, n] = size(A);
[~, rows] = sort(A(:,2:2:n)); %// indices to sort columns 2, 4,...
ind = bsxfun(@plus, rows, (0:n/2-1)*2*m); %// convert to linear index
y = NaN(m,n);
y(:,2:2:n) = A(ind+m); %// fill columns 2, 4,... sorted
y(:,1:2:n) = A(ind); %// fill columns 1, 3,... with the same order
toc
运行时
---------------------------------------- With vectorized approach
Elapsed time is 2.244272 seconds.
---------------------------------------- With loop based approach
Elapsed time is 3.255867 seconds.
---------------------------------------- With Luis Vectorized approach
Elapsed time is 2.800249 seconds.