繁体   English   中英

在MATLAB中将矩阵中每列的非零元素改组

[英]Shuffling non-zero elements of each column in a matrix in MATLAB

我想对矩阵中每一列的非零元素进行混洗,但将零元素保留在同一位置。 像我这样:

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),并且非零元素被混洗了。 显然,使用“ randperm”对列进行改组是行不通的,因为它不允许我将零保持在同一位置!

这是显式循环列方法的替代方法:

[~, jj, vv] = find(A);
s = accumarray(jj, vv, [], @(x){x(randperm(numel(x)))});
B = A;
B(B~=0) = cell2mat(s);

这是一种适用于一列的解决方案:制作一个包含非零条目的新向量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

在线尝试!

我为你写了一个函数

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

它没有优化,我留给您。 它将非零值提取到一个向量,如果旧矩阵在那里没有0,则从该向量中提取randperm值到新矩阵。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM