如何在MATLAB中随机置换3D矩阵中的列

|| 我有3D矩阵(10000 x 60 x 20),并且需要置换第二和第三维以保持列完整。 对于2D矩阵,我使用RANDPERM:
pidx = randperm(size(A,2));
Aperm = A(:,pidx);
我不能只两次应用RANDPERM-首先是列索引,然后是页面索引。随机性不足。 一种解决方案是将矩阵从3D压缩为2D,将列和页面压缩为列,对其进行置换,然后重新成形。但是我也想以这样的方式进行排列,即每个页面的列独立排列。就像是:
Aperm = zeros(size(A));
for p=1:size(A,3)
    pidx = randperm(size(A,2));
    Aperm(:,:,p) = A(:,pidx,p);
end
我可以更有效地做到吗?还有更好的方法吗?     
已邀请:
        解决方案#1:在所有页面上排列列   将矩阵从3D重塑为2D   将列和页面压缩到   列,置换它们,然后重塑   背部
A = randi(10, [3 4 2]);                 %# some random 3D matrix

[r c p] = size(A);
Aperm = reshape(A, [r c*p]);
Aperm = reshape(Aperm(:,randperm(c*p)), [r c p]);
解决方案2:在每个页面中独立地排列列(相当于for循环)   我也想在   这样列排列的方式   每页独立
A = randi(10, [3 4 2]);                 %# some random 3D matrix

[r c p] = size(A);
Aperm = reshape(A, [r c*p]);

[~,idx] = sort(rand(p,c),2);            %# this is what RANDPERM does
idx = reshape(bsxfun(@plus, idx\',0:c:c*(p-1)),1,[]);    %\'#

Aperm = reshape(Aperm(:,idx), [r c p]);
    
        这是一种解决方案,将实现与for循环相同的结果(即,每个页面的列排列不同):
%# Solution 1:
[r,c,p] = size(A);
Aperm = reshape(A,r,c*p);
index = arrayfun(@randperm,c.*ones(1,p),\'UniformOutput\',false);
index = [index{:}]+kron(0:c:c*(p-1),ones(1,c));
Aperm = reshape(Aperm(:,index),r,c,p);
而且,与MATLAB中的许多问题一样,有许多不同的方法可以解决此问题。这是另一种解决方案,通过仅使用线性索引到
A
来避免矩阵重塑:
%# Solution 2:
[r,c,p] = size(A);
Aperm = zeros([r c p]);
index1 = repmat(1:r,1,c*p);
[~,index2] = sort(rand(c,p));          %# A variation on part of Amro\'s answer
index2 = kron(index2(:),ones(r,1)).\';  %\'
index3 = kron(1:p,ones(1,r*c));
index = sub2ind([r c p],index1,index2,index3);
Aperm(:) = A(index);
    
        这是与您的循环相同的解决方案,但不像gnovice的答案中那样使用
kron
。尽管我更喜欢
kron
,但是如果您碰巧与不了解
kron
在这里做什么的人共享代码,这是一个更安全的选择(我是从经验中得出的)。但是我必须注意,如果
pages
变大,这会影响性能(在您的情况下,这是可以的)。
[rows,cols,pages]=size(A);
randCols=arrayfun(@(x)randperm(cols),1:pages,\'UniformOutput\',false);
Aperm=arrayfun(@(x)A(:,randCols{x},x),1:pages,\'UniformOutput\',false);
Aperm=cat(3,Aperm{:});
    

要回复问题请先登录注册