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

时间:2014-08-29 06:34:13

标签: 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

此功能完全符合我的要求,但我的列非常长(> 10,000,000),因此需要很长时间才能运行。有谁知道更快的实现方法?我试过分别摇动每个列向量,但这并不快。谢谢!

4 个答案:

答案 0 :(得分:8)

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

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

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

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

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

[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

会大大减少对randperm的调用次数。将其分解为k相等大小的集可能不是最佳的,您可能还想为其添加一些随机性。这里的基本想法是,只有factorial(m)个不同的排序,如果m远小于n(例如m=5n=100000就像你的数据),然后这些排序将自然重复。因此,不要让它自己发生,而是管理流程并减少对randperm的调用,这无论如何都会产生相同的结果。

答案 1 :(得分:5)

使用randperm获取改组指数

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

使用索引来混洗矢量:

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

看看这个答案:Matlab: How to random shuffle columns of matrix

答案 2 :(得分: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

答案 3 :(得分:4)

这是一种无循环的方法,因为它一次处理所有索引,我相信这是随机的,因为只能在每列之间进行混洗。

<强>代码

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

最终输出是在a本身获得的。