How to shift zero in the last column of a matrix

前端 未结 7 1485
我在风中等你
我在风中等你 2020-12-11 10:58

I have one matrix like below-

A=[1 1 1 1 1;
   0 1 1 1 2;
   0 0 1 1 3]

But I want to place all the 0 at the end of the row, s

相关标签:
7条回答
  • 2020-12-11 11:04

    I've also asked this question and got a super elegant answer (non of above answers is same) here: Optimize deleting matrix leading zeros in MATLAB

    0 讨论(0)
  • If your zeros are always together, you could use the circshift command. This shifts values in an array by a specified number of places, and wraps values that run off the edge over to the other side. It looks like you would need to do this separately for each row in A, so in your example above you could try:

    A(2,:) = circshift(A(2,:), [1 -1]);    % shift the second row one to the left with wrapping
    A(3,:) = circshift(A(3,:), [1 -2]);    % shift the third row two to the left with wrapping
    

    In general, if your zeros are always at the front of the row in A, you could try something like:

    for ii = 1:size(A,1)                              % iterate over rows in A
        numShift = numel(find(A(ii,:) == 0));         % assuming zeros at the front of the row, this is how many times we have to shift the row.
        A(ii,:) = circshift(A(ii,:), [1 -numShift]);  % shift it
    end
    
    0 讨论(0)
  • 2020-12-11 11:08

    there are many ways to do this. one fast way can be easily like this:

    a = [1 2 3 4 0 5 7 0];
    
    idx=(find(a==0));
    
    idx =
    
         5     8
    
    b=a;   % save a new copy of the vector
    b(idx)=[];    % remove zero elements
    
    b =
    
         1     2     3     4     5     7
    
    c=[b zeros(size(idx))]
    
    c =
    
         1     2     3     4     5     7     0     0
    

    You may modify this code as well.

    0 讨论(0)
  • 2020-12-11 11:18

    @LuisMendo's answer is inspiring in its elegance, but I couldn't get it to work (perhaps a matlab version thing). The following (based on his answer) worked for me:

    Aaux = fliplr(reshape([1:numel(A)],size(A)));
    Aaux(find(A==0))=0;
    [Asort iso]=sort(Aaux.',1,'descend');
    iso = iso + repmat([0:size(A,1)-1]*size(A,2),size(A,2),1);
    A=A.';
    A(iso).'
    
    0 讨论(0)
  • 2020-12-11 11:19

    A more generic example:

    A = [1 3 0 1 1;
         0 1 1 1 2;
         0 0 1 1 3]
    
    % Sort columns directly
    [~,srtcol] = sort(A == 0,2);
    % Sorted positions 
    sz  = size(A);
    pos = bsxfun(@plus, (srtcol-1)*sz(1), (1:sz(1))'); % or use sub2ind
    

    The result

    B = A(pos)
    B =
         1     3     1     1     0
         1     1     1     2     0
         1     1     3     0     0
    
    0 讨论(0)
  • 2020-12-11 11:23

    There you go. Whole matrix, no loops, works even for non-contiguous zeros:

    A = [1 1 1 1 1; 0 1 1 1 2; 0 0 1 1 3];
    
    At = A.'; %// It's easier to work with the transpose
    [~, rows] = sort(At~=0,'descend'); %// This is the important part.
    %// It sends the zeros to the end of each column
    cols = repmat(1:size(At,2),size(At,1),1);
    ind = sub2ind(size(At),rows(:),cols(:));
    sol = repmat(NaN,size(At,1),size(At,2));
    sol(:) = At(ind);
    sol = sol.'; %'// undo transpose
    

    As usual, for Matlab versions that do not support the ~ symbol on function return, change ~ by a dummy variable, for example:

    [nada, rows] = sort(At~=0,'descend'); %// This is the important part.
    
    0 讨论(0)
提交回复
热议问题