简体   繁体   English

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

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

I want to shuffle non-zero elements of each column in a matrix but keep the zero elements at the same place. 我想对矩阵中每一列的非零元素进行混洗,但将零元素保留在同一位置。 Like I have this: 像我这样:

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]

And I want this: 我想要这个:

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]

So herein I have the zeros at the exact same place (ie ~A = ~B) and the non-zero elements are shuffled. 所以在这里我在完全相同的位置有零(即〜A =〜B),并且非零元素被混洗了。 Obviously shuffling the columns using 'randperm' does not work as it does not allow me to keep zeroes at the same place! 显然,使用“ randperm”对列进行改组是行不通的,因为它不允许我将零保持在同一位置!

Here's an alternative to the explicit loop-over-columns approach: 这是显式循环列方法的替代方法:

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

This is a solution that works for one column: Making a new vector C containing the nonzero entries, shuffling those, and pasting them back into the nonzero entries of B should do exactly that. 这是一种适用于一列的解决方案:制作一个包含非零条目的新向量C ,对它们进行混洗,然后将其粘贴回B的非零条目中,就应该做到这一点。 Now you can adjust this to work for matrices by looping over all columns. 现在,您可以通过遍历所有列来将其调整为适用于矩阵。

A =  [10, 11, 0, 13, 0, 15, 16];
B = A;
C = A(A~=0);
B(A~=0) = C(randperm(numel(C)));
A
B

Try it online! 在线尝试!

I wrote a function for you 我为你写了一个函数

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

It's not optimized, I leave it to You. 它没有优化,我留给您。 It extracts the non-zeros to a vector, and takes randperm values from this vector to the new matrix, if the old matrix didnt have 0 there. 它将非零值提取到一个向量,如果旧矩阵在那里没有0,则从该向量中提取randperm值到新矩阵。

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

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