How to flip non-zero elements of an array and keep zero elements at initial position?

9 views (last 30 days)
A LL on 8 Mar 2022
Edited: Les Beckham on 8 Mar 2022
I have an array (A) with non-zero elements and zero elements.
I want to flip all non-zero elements of A but keep all zero elements at their initial position to get B.
I tried this and it works but I am sure there is a one-liner-ish solution to my problem:
A = [1 2 3 4 5 0];
nz = nnz(A); %nz=5
N = numel(A); %N=6
numZend = N-nz; %numZend = 1
Zend = zeros(numZend); %Zend = 0
A1 = flip(nonzeros(A));%A1 = [5 4 3 2 1]'
B = [A1',Zend]; %B = [5 4 3 2 1 0]
Note that my zero elements are always at the end of my array. I can have 0 to 5 zero elements at the end of my array. Normally, length(A) ranges between 17 and 22.
Thank you :)
2 CommentsShowHide 1 older comment
A LL on 8 Mar 2022
Edited: A LL on 8 Mar 2022
In my case, my zeros are always located at the end of my matrix with something like this:
A=[randi([1,9],5,3);zeros(2,3)]
I tried this, it works but it seems a bit too complicated for what I am trying to do:
A =[randi([1,9],5,3);zeros(2,3)];
nz = nnz(A(:,1));
N = numel(A(:,1));
numZend = N-nz;
Zend = zeros(numZend,numel(A(1,:)));
A1 = flip(A,1);
A2 = A1(numZend+1:end,:);
B = [A2;Zend];
Would you have an idea to make this simpler?

Sign in to comment.

Accepted Answer

Les Beckham on 8 Mar 2022
Another possibility (still requires a loop):
A = [ 134 159 122 175 126 0 0
151 170 189 196 0 0 0
155 114 115 126 184 125 0 ]; % test data
B = zeros(size(A));
for i = 1:size(A, 1)
inz = A(i,:)~=0; % logical indices of non-zero elements
B(i,inz) = flip(A(i,inz)) % flip the non-zero elements in this row
end
1 CommentShowHide None
Les Beckham on 8 Mar 2022
Edited: Les Beckham on 8 Mar 2022
If all rows of the array have the same number of columns of zeros it is possible to do this without the loop.
A = [ 134 159 122 175 126 0 0
151 170 189 196 125 0 0
155 114 115 126 184 0 0 ]; % test data -- modified
B = zeros(size(A));
[r, c] = find(A~=0);
B(A~=0) = fliplr(A(unique(r), unique(c)))
B = 3×7
126 175 122 159 134 0 0 125 196 189 170 151 0 0 184 126 115 114 155 0 0
Not exactly pretty, but it works. I think I like the loop better since it works for different numbers of zeros in each row and is a little easier to follow.

Sign in to comment.

More Answers (3)

David Hill on 8 Mar 2022
A = [1 2 3 4 5 0];
a=flip(A(A~=0));
a=[a,zeros(1,length(A)-length(a))];
1 CommentShowHide None
A LL on 8 Mar 2022
Edited: A LL on 8 Mar 2022
Thank you for your answer. :)
Do you have a way to generalize this?
My A is in fact a 20x3 matrix with 2x3 zeros at the end.
Using the nonzeros function (A~=0) returns a full column vector so this will be problematic with A that has dimension greater than 1.

Sign in to comment.

DGM on 8 Mar 2022
Edited: DGM on 8 Mar 2022
I'm sure there's something simpler, but this is what my sleeplessness created:
A = [1:5 0; 11:14 0 0; 21:23 0 0 0; 31 0 32 0 33 0];
A = A.';
mask = A~=0;
B = zeros(size(A));
B(flipud(mask)) = A(mask);
B = flipud(B).'
B = 4×6
5 4 3 2 1 0 14 13 12 11 0 0 23 22 21 0 0 0 33 0 32 0 31 0
0 CommentsShowHide -1 older comments

Sign in to comment.

Image Analyst on 8 Mar 2022
Does this do what you want:
% Generate sample data.
A = zeros(6, 10);
for row = 1 : size(A, 1)
numNonZeros = randi([3,7]); % Between 3 and 7 non-zeros to start each row.
A(row, 1:numNonZeros) = randi(9, 1, numNonZeros);
end
A
A = 6×10
5 9 8 3 2 0 0 0 0 0 6 4 8 0 0 0 0 0 0 0 9 2 8 9 6 0 0 0 0 0 9 6 9 2 0 0 0 0 0 0 1 4 8 4 7 3 0 0 0 0 7 3 2 6 0 0 0 0 0 0
% Now we have A, let's flip the non-zeros row-by-row
AFlipped = zeros(size(A));
for row = 1 : size(A, 1)
lastCol = find(A(row,:) ~= 0, 1, 'last');
AFlipped(row, 1:lastCol) = fliplr(A(row, 1:lastCol)); % Do the flip of non-zeros ONLY
end
AFlipped % Show in command window.
AFlipped = 6×10
2 3 8 9 5 0 0 0 0 0 8 4 6 0 0 0 0 0 0 0 6 9 8 2 9 0 0 0 0 0 2 9 6 9 0 0 0 0 0 0 3 7 4 8 4 1 0 0 0 0 6 2 3 7 0 0 0 0 0 0
1 CommentShowHide None
A LL on 8 Mar 2022
Yes, it does! Thank you very much!
It is even more general than what I need since, in my case, I always have a fix number of zero for each row.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!