在MATLAB中有一个更好/更快的方法随机改组矩阵吗?

use*_*089 5 arrays matlab matrix

在MATLAB中,我使用shake.m函数(http://www.mathworks.com/matlabcentral/fileexchange/10067-shake)随机随机播放每列.例如:

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
Run Code Online (Sandbox Code Playgroud)

这个函数正是我想要的,但是我的列长(> 10,000,000),所以这需要很长时间才能运行.有谁知道更快的实现方法?我试过分别摇动每个列向量,但这并不快.谢谢!

Dan*_*Dan 8

你可以randperm像这样使用,但我不知道它是否会比shake以下更快:

[m,n]=size(a)
for c = 1:n
    a(randperm(m),c) = a(:,c);
end
Run Code Online (Sandbox Code Playgroud)

或者您可以尝试切换randperm四周以查看哪个更快(应该产生相同的结果):

[m,n]=size(a)
for c = 1:n
    a(:,c) = a(randperm(m),c);
end
Run Code Online (Sandbox Code Playgroud)

否则你有多少行?如果你的行数少于列数,那么我们可以假设每个排列都会重复,那么这样的事情怎么样:

[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
Run Code Online (Sandbox Code Playgroud)

这将大大减少呼叫次数randperm.将其分解为k相同大小的集合可能不是最佳的,您可能也想要添加一些随机性.这里的基本思想是,只有factorial(m)不同的顺序,如果mn(例如m=5,n=100000像你的数据)小得多,那么这些顺序将自然重复.因此,不是让它自己发生,而是管理流程并减少randperm无论如何都会产生相同结果的调用.


lak*_*esh 5

使用randperm获得改组的指数

idx = randperm(size(a,1));
Run Code Online (Sandbox Code Playgroud)

使用索引来调整向量:

m = size(a,1);
for i=1:m
 b(:,i) = a(randperm(m,:);
end
Run Code Online (Sandbox Code Playgroud)

看看这个答案:Matlab:如何随机改组矩阵列


Lui*_*ndo 5

这是一个简单的矢量化方法.请注意,它会创建一个与之ind相同大小的辅助矩阵()a,因此根据您的记忆,它可能是否可用.

[~, 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
Run Code Online (Sandbox Code Playgroud)