我想打乱一个具有复杂值的三维数组,使元素仅沿三维随机重新排列。
例如,整数A的3D数组(我提醒您,我正在寻找相同的解决方案,但对于复数数字数组(:
A(:,:1)= 1 2 3 ; 4 5 6 ; 7 8 9
A(:,:2)= 10 11 12; 13 14 15 ; 16 17 18
在对第三维进行混洗之后,可能的输出是:
A(:,:1)= 10 2 3 ; 4 14 6 ; 7 17 18
A(:,:2)= 1 11 12; 13 5 15 ; 16 8 9
我该怎么做?
我找到的唯一解决方案包括编译的c函数,它不适用于复值数组。
您可以非常简单地在前两个维度上迭代,并沿着第三个维度排列元素:
a = randn(3,5,2) + 1i*randn(3,5,2); % some complex data
for jj=1:size(a,2)
for ii=1:size(a,1)
a(ii,jj,:) = a(ii,jj,randperm(size(a,3)));
end
end
请注意,对于非常大的阵列,此解决方案可能比另一个答案中的cellfun
解决方案更快,因为该解决方案需要存储和使用大型中间数据。
这里有一种矢量化的方法:
A = cat(3, [1 2 3; 4 5 6; 7 8 9], [10 11 12; 13 14 15; 16 17 18]); % define data
s = size(A); % get size of A
[~, ind] = sort(rand(s), 3); % indices of random permutations along 3rd dim
result = A(reshape(1:s(1)*s(2),s(1),s(2)) + (ind-1)*s(1)*s(2)); % linear index and result
下面的脚本在三维中进行随机洗牌
% creating a sample data, can be complex numbers
x=magic(10);
x=reshape(x,[4,5,5]);
% split 3D matrix into 2D cell arrays of vectors, permute those, and get back to 3D
y=num2cell(x,3);
newy=cellfun(@(x) x(randperm(length(x))), y,'uni',false);
newx=cell2mat(newy);
可以先调用permute
,然后调用num2cell
,以不同的方式对3D阵列进行分区,从而将其打乱到不同的维度,例如
x=permute(x,[2,3,1]);
y=num2cell(x,3);
上面的代码将创建一个由4个元素(即第1维(的向量组成的5x5单元阵列,然后您可以使用cellfun/cell2mat
对第1维进行随机洗牌,然后再次调用permute
将其更改回原始维度顺序。