# Replace zero in a matrix with value in previous row

23 views (last 30 days)
Mohit on 1 Feb 2014
Edited: DGM on 3 Dec 2022
Hi,
Can you please help me on how can I replace all zeroes in a matrix with the value in previous row?
e.g. if value in row 3 column 4 is 0, it should pick value in row 2 column 4.
I can do it using a for loop but I dont want to use that.
Thanks.

Azzi Abdelmalek on 1 Feb 2014
Edited: Azzi Abdelmalek on 1 Feb 2014
A=[1 2 3 4;4 5 0 0;1 0 0 1 ;0 1 1 1]
while any(A(:)==0)
ii1=A==0;
ii2=circshift(ii1,[-1 0]);
A(ii1)=A(ii2);
end
Jan on 4 Nov 2016
match = (A(:, 3)==0);
A(match, 3) = A(match, 2);
Pardis on 16 Mar 2020

Shivaputra Narke on 1 Feb 2014
while(all(a(:))) a(find(a==0))=a(find(a==0)-1) end
##### 3 CommentsShow 1 older commentHide 1 older comment
Captain Karnage on 2 Dec 2022
That expression doesn't work as written in a single line. Without a ; after the assignment, it gets an error 'Error: Illegal use of reserved keyword "end".` If I add the ; however, it doesn't error but it still doesn't work. I'm not sure why, because logically it seems like it should, but I just get the original a out when I run it.
DGM on 3 Dec 2022
Edited: DGM on 3 Dec 2022
The loop is never entered at all. You could make some modifications.
a = [0 5 9 13; 2 6 0 0; 3 0 0 15; 0 8 12 16]
a = 4×4
0 5 9 13 2 6 0 0 3 0 0 15 0 8 12 16
na = numel(a);
while ~all(a(:)) % loop runs until there are no zeros
idx = find(a==0);
a(idx) = a(mod(idx-2,na)+1);
end
a
a = 4×4
16 5 9 13 2 6 9 13 3 6 9 15 3 8 12 16
The redundant find() can be removed. Since this is based on decrementing the linear indices, this will fill zeros at the top of a column with content from the bottom of the prior column. Using mod() allows the wrapping behavior to extend across the ends of the array. Note that a(1,1) is filled from a(16,16).
Whether this wrapping behavior is intended or acceptable is a matter for the reader to decide.

Andrei Bobrov on 1 Feb 2014
l = A == 0;
ii = bsxfun(@plus,size(A,1)*(0:size(A,2)-1),cumsum(~l));
out = A;
out(l) = A(ii(l));

Shivaputra Narke on 1 Feb 2014
May be this code can help...
% where a is your matrix a(find(a==0))=a(find(a==0)-1)
Amit on 1 Feb 2014
This will not work in many scenarios.
Mohit on 1 Feb 2014
Thanks a lot, it works!
What should I do in case I want to put another condition that if cell value above zero cell is also zero then go one cell up.
e.g. if value in row 6 column 4 is 0, it should pick value in row 5 column 4. If value in row 5 column 4 is also zero then it should pick value in row 4 column 4 and so on.

Amit on 1 Feb 2014
Lets say your matrix is A
[m,n] = size(A);
An = A';
valx = find(~An); % This will give you zeros elements linear index
valx = valx(valx-n > 0);
An(valx) = An(valx-n);
A = An';
Mohit on 1 Feb 2014
Thanks

Paul on 1 Feb 2014
idx=find(A==0)
A(idx)=A(idx-1)
##### 3 CommentsShow 1 older commentHide 1 older comment
Shivaputra Narke on 1 Feb 2014
Thank you Amit. My solution wont work on such scenarios.
Mohit on 1 Feb 2014
Thanks