Is there a better / quick way to randomly shuffle a matrix in MATLAB?

In MATLAB, I use the shake.m function ( http://www.mathworks.com/matlabcentral/fileexchange/10067-shake ) to randomly shuffle each column. For instance:

a = [1 2 3; 4 5 6; 7 8 9] a = 1 2 3 4 5 6 7 8 9 b = shake(a) b = 7 8 6 1 5 9 4 2 3 

This function does exactly what I want, however my columns are very long (> 10,000,000), and therefore it takes a lot of time. Does anyone know of a faster way to achieve this? I tried to shake each column vector separately, but it is not faster. Thank you

+5
source share
4 answers

Here's a simple vector approach. Note that it creates an auxiliary matrix ( ind ) of the same size as a , so depending on your memory, it can be used or not.

 [~, ind] = sort(rand(size(a))); %// create a random sorting for each column b = a(bsxfun(@plus, ind, 0:size(a,1):numel(a)-1)); %// convert to linear index 
+5
source

You can use randperm like this, but I don't know if it will be faster than shake :

 [m,n]=size(a) for c = 1:n a(randperm(m),c) = a(:,c); end 

Or you can try switching randperm around to see which is faster (should give the same result):

 [m,n]=size(a) for c = 1:n a(:,c) = a(randperm(m),c); end 

Otherwise, how many lines do you have? If you have far fewer rows than columns, perhaps we can assume that each permutation will repeat, so something like this is something like this:

 [m,n]=size(a) cols = randperm(n); k = 5; %//This is a parameter you'll need to tweak... set_size = floor(n/k); for set = 1:set_size:n set_cols = cols(set:(set+set_size-1)) a(:,set_cols) = a(randperm(m), set_cols); end 

which would significantly reduce the number of calls to randperm . Splitting it into k sets of equal size may not be optimal, although you may want to add some randomness to them. The main idea here is that there will only be factorial(m) different orderings, and if m much less than n (for example, m=5 , n=100000 as your data), then these orderings will be repeated naturally, Therefore, instead of to allow this to happen on its own, rather control the process and reduce the number of calls to randperm , which in any case will produce the same result.

+8
source

Get shuffled indexes using randperm

 idx = randperm(size(a,1)); 

Use indexes to shuffle a vector:

 m = size(a,1); for i=1:m b(:,i) = a(randperm(m,:); end 

Have a look at this answer: Matlab: how to randomly shuffle matrix columns

+5
source

There is no loopback approach, since it processes all indexes at once, and I think this is as random as you can get, given the shuffling requirements between each column.

the code

 %// Get sizes [m,n] = size(a); %// Create an array of randomly placed sequential indices from 1 to numel(a) rand_idx = randperm(m*n); %// segregate those indices into rows and cols for the size of input data, a col = ceil(rand_idx/m); row = rem(rand_idx,m); row(row==0)=m; %// Sort both these row and col indices based on col, such that we have col %// as 1,1,1,1 ...2,2,2,....3,3,3,3 and so on, which would represent per col %// indices for the input data. Use these indices to linearly index into a [scol,ind1] = sort(col); a(1:m*n) = a((scol-1)*m + row(ind1)) 

The end result is obtained in a .

+4
source

Source: https://habr.com/ru/post/1201387/


All Articles