Matlab 每隔一列排序
Matlab sort every other column
我有这样的重复模式数据-
years cf1 years cf2
2010 45 2010 37
2011 39 2011 29
2012 51 2012 31
2013 25 2013 33
2014 35 2014 28
我需要数据或数组在按 "cfX" 变量排序后每隔一列看起来像这样。
years cf1 years cf2
2013 25 2014 28
2014 35 2011 29
2011 39 2012 31
2010 45 2013 33
2012 51 2010 37
非常感谢您的帮助!
对于每组两列,您可以使用 sortrows
。
for idx=1:2:size(M,2)
M(:,idx:idx+1)=sortrows(M(:,idx:idx+1),2)
end
另一种基于循环的方法,仅使用排序:
disp('---------------------------------------- With other loop based approach')
tic
Aout3 = zeros(size(A));
for i=0:size(A,2)/2-1
[ord iord]=sort(A(:,2*i+2),'ascend');
Aout3(:,2*i+1)=A(iord,2*i+1);
Aout3(:,2*i+2)=ord;
end
toc
将此添加到 ,对于 A=rand(5000)
我得到:
---------------------------------------- With vectorized approach
Elapsed time is 1.415872 seconds.
---------------------------------------- With loop based approach
Elapsed time is 1.997568 seconds.
---------------------------------------- With Luis Vectorized approach
Elapsed time is 1.560120 seconds.
---------------------------------------- With other loop based approach
Elapsed time is 1.566022 seconds.
矢量化方法
这假设 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));
基准测试
本节将提出的矢量化方法与 and 中列出的基于循环的方法进行基准测试。
基准代码
%// 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.
这是另一种矢量化方法。让 x
表示您的矩阵。
[m, n] = size(x);
[~, rows] = sort(x(:,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); %// you can remove this line if `y` is assured not to exist,
%// because in that case the next line serves as preallocation
y(:,2:2:n) = x(ind+m); %// fill columns 2, 4,... sorted
y(:,1:2:n) = x(ind); %// fill columns 1, 3,... with the same order
我有这样的重复模式数据-
years cf1 years cf2
2010 45 2010 37
2011 39 2011 29
2012 51 2012 31
2013 25 2013 33
2014 35 2014 28
我需要数据或数组在按 "cfX" 变量排序后每隔一列看起来像这样。
years cf1 years cf2
2013 25 2014 28
2014 35 2011 29
2011 39 2012 31
2010 45 2013 33
2012 51 2010 37
非常感谢您的帮助!
对于每组两列,您可以使用 sortrows
。
for idx=1:2:size(M,2)
M(:,idx:idx+1)=sortrows(M(:,idx:idx+1),2)
end
另一种基于循环的方法,仅使用排序:
disp('---------------------------------------- With other loop based approach')
tic
Aout3 = zeros(size(A));
for i=0:size(A,2)/2-1
[ord iord]=sort(A(:,2*i+2),'ascend');
Aout3(:,2*i+1)=A(iord,2*i+1);
Aout3(:,2*i+2)=ord;
end
toc
将此添加到 A=rand(5000)
我得到:
---------------------------------------- With vectorized approach
Elapsed time is 1.415872 seconds.
---------------------------------------- With loop based approach
Elapsed time is 1.997568 seconds.
---------------------------------------- With Luis Vectorized approach
Elapsed time is 1.560120 seconds.
---------------------------------------- With other loop based approach
Elapsed time is 1.566022 seconds.
矢量化方法
这假设 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));
基准测试
本节将提出的矢量化方法与
基准代码
%// 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.
这是另一种矢量化方法。让 x
表示您的矩阵。
[m, n] = size(x);
[~, rows] = sort(x(:,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); %// you can remove this line if `y` is assured not to exist,
%// because in that case the next line serves as preallocation
y(:,2:2:n) = x(ind+m); %// fill columns 2, 4,... sorted
y(:,1:2:n) = x(ind); %// fill columns 1, 3,... with the same order