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 ?

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

I don't understand where the 2 and 3 come from. Do you mean you want to interpolate between 222 and 312?
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

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

Yes, but this defaults to cubic, he wants the nearest neighbour I think.
"vq = interp1(x,v,xq,method) specifies any of five strings for choosing an alternative interpolation method: 'nearest', 'linear','spline','pchip', or 'cubic'. The default method is 'linear'."
So I did linear. All I saw in his post was that he wants to interpolate. Where are you seeing that he wants any particular method?

Sign in to comment.

More Answers (1)

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;

Categories

Find more on Interpolation in Help Center and File Exchange

Asked:

on 20 Feb 2014

Commented:

Lee
on 2 Feb 2018

Community Treasure Hunt

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

Start Hunting!