How can I find all zeros in a vector and change those values by interpolating the last number before zero and the first number after zero ?

24 views (last 30 days)
Hi all,
I have a vector of data including zeros. I want to find and delete all zeros and interpolate the missing values.
For instance:
A=[123 443 652 222 0 0 0 0 0 0 312 5 6]
In this case, I want to interpolate between 2 and 3.
Since I am quite new to MATLAB, I don't know how to do that.
Many thanks.
  5 Comments
Julian Williams
Julian Williams on 20 Feb 2014
Edited: Julian Williams on 20 Feb 2014
This I can help with a bit, you use the wonderfully helpful interp1 function.
There is an automated system Vq = interp1(X,V,Xq,METHOD,EXTRAPVAL), that does this, just check the interp1 help. For a bit more control try this:
Say you have Y = [2 3 1 0 0 0 4 7 2 8]'; The zeros are possibly an artifact from extracting the data or occur for some other reason.
If you don't have specific abscissa values then you could create a vector that spaces them equally, for instance X = [1 2 3 4 5 6 7 8 9 10]';
now find and make an index of the zeros I = find(Y == 0); Matlab seems to prefer using I = (Y == 0) these days, but I am old!
Now create another vector of abscissa values Xi = X;
Then extract the zeros using the index:
X(I)=[];Y(I)=[];
Now use the one dimensional interpolation:
Yi = interp1(X,Y,Xi,method);
for method choose the one that suits you best, from the post I think you want 'nearest', most people use 'cubic' to get a smooth curve between the points.
So complete code is:
Y = [2 3 1 0 0 0 4 7 2 8]'; X = [1 2 3 4 5 6 7 8 9 10]'; Xi = X;I = find(Y == 0); X(I)=[];Y(I)=[]; Yi = interp1(X,Y,Xi,method);
This gives me:
Yi = [2 3 1 1 4 4 4 7 2 8]'
interp1 does not need you specify the abscissa values X, however you probably want to control the location of the missing values.
E.g. for your example I would use:
A=[123 443 652 222 0 0 0 0 0 0 312 5 6]'; N=length(A);X=(1:N)'; I=find(A==0);Xi=X;X(I)=[];A(I)=[]; Ai=interp1(X,A,Xi,'nearest');
And this gives me:
Ai = [123 443 652 222 222 222 222 312 312 312 312 5 6]'
in the title of your question you talked about which number is used by the nearest neighbor, if you need to control this then you just need to flip the vector then unflip it using flipud assuming it is a column vector.

Sign in to comment.

Accepted Answer

Image Analyst
Image Analyst on 20 Feb 2014
One way is to use interp1():
A=[123 443 652 222 0 0 0 0 0 0 312 5 6]
x = 1:length(A)
xi = 1:length(A)
zs = A==0 % Zeros locations
A(zs) = []
x(zs)=[]
output = interp1(x, A, xi)
  4 Comments

Sign in to comment.

More Answers (1)

Matt J
Matt J on 20 Feb 2014
There are lots of inpainting routines on the File Exchange
Most of them assume that your missing data is represented by NaNs, so you would first have to convert your zeros to NaNs,
A(~A)=nan;

Community Treasure Hunt

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

Start Hunting!