我想要在矩阵中混洗每列的非零元素,但是将零元素保持在同一个位置。就像我有这个:
A =
[10 0 30 40 50 60
11 0 31 41 0 61
0 22 32 42 0 62
13 23 0 43 0 63
0 24 34 44 54 64
15 0 35 0 0 65
16 26 36 46 56 66]
我想要这个:
B =
[13 0 32 44 54 64
11 0 35 42 0 63
0 24 36 40 0 61
16 23 0 43 0 62
0 22 31 41 56 60
10 0 30 0 0 66
15 26 34 46 50 65]
因此,我在完全相同的位置(即~A = ~B)处有零,并且非零元素被混洗。显然使用&raffperm'拖曳柱子。不起作用,因为它不允许我在同一个地方保留零!
答案 0 :(得分:3)
这是显式循环列方法的替代方法:
[~, jj, vv] = find(A);
s = accumarray(jj, vv, [], @(x){x(randperm(numel(x)))});
B = A;
B(B~=0) = cell2mat(s);
答案 1 :(得分:2)
这是一个适用于一列的解决方案:创建一个包含非零条目的新向量C
,对它们进行混洗,然后将它们粘贴回B
的非零条目中应该完全相同。现在,您可以通过循环遍历所有列来调整此值以适用于矩阵。
A = [10, 11, 0, 13, 0, 15, 16];
B = A;
C = A(A~=0);
B(A~=0) = C(randperm(numel(C)));
A
B
答案 2 :(得分:1)
我为你写了一个函数
function a=shuffle(src)
[rows, cols] = size(src);
a = zeros(rows,cols);
for c = 1:cols
lastIndex = 1;
col = [];
for r = 1:rows
if(src(r,c) ~= 0)
col(lastIndex) = src(r,c);
lastIndex = lastIndex + 1;
end
end
indexes = randperm(length(col));
lastIndex = 1;
for r = 1:rows
if(src(r,c) == 0)
a(r,c) = 0;
else
a(r,c) = col(indexes(lastIndex));
lastIndex = lastIndex + 1;
end
end
end
end
它没有优化,我留给你。 它将非零提取到一个向量,并将该向量中的randperm值带到新矩阵,如果旧矩阵在那里没有0。