Matlab sorts each column

I have data similar to this in a repeating pattern -

years cf1 years cf2 2010 45 2010 37 2011 39 2011 29 2012 51 2012 31 2013 25 2013 33 2014 35 2014 28 

I need the data or array to look like every other column is sorted by the variable "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 

Thank you so much for your help!

-2
sorting arrays matrix matlab
source share
4 answers

For each set of two columns, you can use sortrows .

 for idx=1:2:size(M,2) M(:,idx:idx+1)=sortrows(M(:,idx:idx+1),2) end 
+4
source share

Vectorized Approach

This suggests that A is an input matrix.

 [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)); 

The last line can be replaced with the following code, which seems to provide minor runtime improvements for small data -

 Aout = A(bsxfun(@plus,reshape(repmat(id,2,1),m,n),[0:n-1]*m)); 

Benchmarking

This section analyzes the proposed loop-based vectorized approach approaches listed in @Daniel's answer and later added by @Luis .

Benchmarking code

 %// 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 mn 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 

Runtimes

 ---------------------------------------- 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. 
+4
source share

Here is another vector approach. Let x denote your matrix.

 [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 
+3
source share

Another loop based approach using only sorting:

 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 

Add this to the tag, for A=rand(5000) I get:

 ---------------------------------------- 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. 
+2
source share

All Articles