Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Interpolation between data points with NaN

Subject: Interpolation between data points with NaN

From: Elom

Date: 6 Apr, 2011 20:34:04

Message: 1 of 7

I have some data points that I would like to interpolate between the sets.
eg:
y = [ 3 2 NaN 4 2 1 NaN NaN NaN 4 2 NaN 6];
I want to find place an average between two numbers where there is a NaN and empty out the cases where there is more than one NaN value consecutively. For example, in the case above, y3 = NaN and I would like to replace y3 by (y2+y4)/2 and remove y7:y9.. etc.

Subject: Interpolation between data points with NaN

From: John D'Errico

Date: 6 Apr, 2011 20:53:04

Message: 2 of 7

"Joe" wrote in message <iniins$3h0$1@fred.mathworks.com>...
> I have some data points that I would like to interpolate between the sets.
> eg:
> y = [ 3 2 NaN 4 2 1 NaN NaN NaN 4 2 NaN 6];
> I want to find place an average between two numbers where there is a NaN and empty out the cases where there is more than one NaN value consecutively. For example, in the case above, y3 = NaN and I would like to replace y3 by (y2+y4)/2 and remove y7:y9.. etc.

An option is inpaint_nans.

y = [ 3 2 NaN 4 2 1 NaN NaN NaN 4 2 NaN 6];
inpaint_nans(y)
ans =
   3 2 3.1667 4 2 1 1.6 2.9 4 4 2 3.2 6

Find it on the file exchange. It does something a little
more sophisticated than what you thought to do, but
who cares?

http://www.mathworks.com/matlabcentral/fileexchange/4551

John

Subject: Interpolation between data points with NaN

From: TideMan

Date: 6 Apr, 2011 23:44:43

Message: 3 of 7

On Apr 7, 8:53 am, "John D'Errico" <woodch...@rochester.rr.com> wrote:
> "Joe" wrote in message <iniins$3h...@fred.mathworks.com>...
> > I have some data points that I would like to interpolate between the sets.
> > eg:
> > y = [ 3 2 NaN 4 2 1 NaN NaN NaN 4 2 NaN 6];
> > I want to find place an average between two numbers where there is a NaN and empty out the cases where there is more than one NaN value consecutively.  For example, in the case above, y3 = NaN and I would like to replace y3 by (y2+y4)/2 and remove y7:y9.. etc.
>
> An option is inpaint_nans.
>
> y = [ 3 2 NaN 4 2 1 NaN NaN NaN 4 2 NaN 6];
> inpaint_nans(y)
> ans =
>    3  2  3.1667  4  2  1  1.6  2.9  4  4  2  3.2  6
>
> Find it on the file exchange. It does something a little
> more sophisticated than what you thought to do, but
> who cares?
>
> http://www.mathworks.com/matlabcentral/fileexchange/4551
>
> John

And here's another one that I think is very elegant (from t_tide by
Rich Pawlowicz):

function y=fixgaps(x);
% FIXGAPS Linearly interpolates gaps in a time series
% YOUT=FIXGAPS(YIN) linearly interpolates over NaN
% in the input time series (may be complex), but ignores
% trailing and leading NaN.
%

% R. Pawlowicz 6/Nov/99

y=x;

bd=isnan(x);
gd=find(~bd);

bd([1:(min(gd)-1) (max(gd)+1):end])=0;


y(bd)=interp1(gd,x(gd),find(bd));

Subject: Interpolation between data points with NaN

From: Joe

Date: 9 Apr, 2011 16:39:04

Message: 4 of 7

"John D'Errico" <woodchips@rochester.rr.com> wrote in message <inijrg$lra$1@fred.mathworks.com>...
> "Joe" wrote in message <iniins$3h0$1@fred.mathworks.com>...
> > I have some data points that I would like to interpolate between the sets.
> > eg:
> > y = [ 3 2 NaN 4 2 1 NaN NaN NaN 4 2 NaN 6];
> > I want to find place an average between two numbers where there is a NaN and empty out the cases where there is more than one NaN value consecutively. For example, in the case above, y3 = NaN and I would like to replace y3 by (y2+y4)/2 and remove y7:y9.. etc.
>
> An option is inpaint_nans.
>
> y = [ 3 2 NaN 4 2 1 NaN NaN NaN 4 2 NaN 6];
> inpaint_nans(y)
> ans =
> 3 2 3.1667 4 2 1 1.6 2.9 4 4 2 3.2 6
>
> Find it on the file exchange. It does something a little
> more sophisticated than what you thought to do, but
> who cares?
>
> http://www.mathworks.com/matlabcentral/fileexchange/4551
>
> John

Thanks. This is good but I forgot to mention that I want to remove the places where there were two or more NaN consecutively. For example, the three NaNs that are between the 1 and the 4 are to be eliminated.

Subject: Interpolation between data points with NaN

From: John D'Errico

Date: 9 Apr, 2011 18:34:04

Message: 5 of 7

"Joe" wrote in message <inq238$qb2$1@fred.mathworks.com>...
> "John D'Errico" <woodchips@rochester.rr.com> wrote in message <inijrg$lra$1@fred.mathworks.com>...
> > "Joe" wrote in message <iniins$3h0$1@fred.mathworks.com>...
> > > I have some data points that I would like to interpolate between the sets.
> > > eg:
> > > y = [ 3 2 NaN 4 2 1 NaN NaN NaN 4 2 NaN 6];
> > > I want to find place an average between two numbers where there is a NaN and empty out the cases where there is more than one NaN value consecutively. For example, in the case above, y3 = NaN and I would like to replace y3 by (y2+y4)/2 and remove y7:y9.. etc.
> >
> > An option is inpaint_nans.
> >
> > y = [ 3 2 NaN 4 2 1 NaN NaN NaN 4 2 NaN 6];
> > inpaint_nans(y)
> > ans =
> > 3 2 3.1667 4 2 1 1.6 2.9 4 4 2 3.2 6
> >
> > Find it on the file exchange. It does something a little
> > more sophisticated than what you thought to do, but
> > who cares?
> >
> > http://www.mathworks.com/matlabcentral/fileexchange/4551
> >
> > John
>
> Thanks. This is good but I forgot to mention that I want to remove the places where there were two or more NaN consecutively. For example, the three NaNs that are between the 1 and the 4 are to be eliminated.

Well, then remove them. Use the isnan function to flag
elements that are nan. Then find blocks of ones in
the result. For example, strfind can search for a pattern
in a vector. What will the locations of the substrings
[0 1] and [1 0] tell you in this respect? Note that these
substrings must alternate in a vector composed of only
0 and 1 elements!

Any blocks longer than your goal you will delete. At that
point, since you will have already found the singleton
nan elements, it is trivial to replace them with an average
of the neighbors.

John

Subject: Interpolation between data points with NaN

From: Joe

Date: 12 Apr, 2011 16:42:05

Message: 6 of 7

"John D'Errico" <woodchips@rochester.rr.com> wrote in message <inq8qs$64c$1@fred.mathworks.com>...
> "Joe" wrote in message <inq238$qb2$1@fred.mathworks.com>...
> > "John D'Errico" <woodchips@rochester.rr.com> wrote in message <inijrg$lra$1@fred.mathworks.com>...
> > > "Joe" wrote in message <iniins$3h0$1@fred.mathworks.com>...
> > > > I have some data points that I would like to interpolate between the sets.
> > > > eg:
> > > > y = [ 3 2 NaN 4 2 1 NaN NaN NaN 4 2 NaN 6];
> > > > I want to find place an average between two numbers where there is a NaN and empty out the cases where there is more than one NaN value consecutively. For example, in the case above, y3 = NaN and I would like to replace y3 by (y2+y4)/2 and remove y7:y9.. etc.
> > >
> > > An option is inpaint_nans.
> > >
> > > y = [ 3 2 NaN 4 2 1 NaN NaN NaN 4 2 NaN 6];
> > > inpaint_nans(y)
> > > ans =
> > > 3 2 3.1667 4 2 1 1.6 2.9 4 4 2 3.2 6
> > >
> > > Find it on the file exchange. It does something a little
> > > more sophisticated than what you thought to do, but
> > > who cares?
> > >
> > > http://www.mathworks.com/matlabcentral/fileexchange/4551
> > >
> > > John
> >
> > Thanks. This is good but I forgot to mention that I want to remove the places where there were two or more NaN consecutively. For example, the three NaNs that are between the 1 and the 4 are to be eliminated.
>
> Well, then remove them. Use the isnan function to flag
> elements that are nan. Then find blocks of ones in
> the result. For example, strfind can search for a pattern
> in a vector. What will the locations of the substrings
> [0 1] and [1 0] tell you in this respect? Note that these
> substrings must alternate in a vector composed of only
> 0 and 1 elements!
>
> Any blocks longer than your goal you will delete. At that
> point, since you will have already found the singleton
> nan elements, it is trivial to replace them with an average
> of the neighbors.
>
> John


Alright maybe it is because I am new to matlab. I have say:
x = [4 NaN 2 4 2 NaN NaN 4 3]';
x1 = x;
k = isnan(x);
for i = 2:length(x);
    if (x(i) == find(isnan(x),1,'first'))
     x1(i) = (x(i+1) + x(i-1))/2;
    elseif x(i) == find(isnan(x),2,'first'))
x(i) = [ ];
else
x1(i) = x(i)
    end
end

What I would like to do is to determine if there is two or more NaN in consecutive order. If there is one, it removes them, else if there is a NaN between two numbers, it finds the average between the two numbers and replace the NaN with the average of the two numbers. Otherwise, the values remain the same.

The result I am expected to get from the above is:
x1 = [4 3 2 4 2 4 3];

Thanks very much.

Subject: Interpolation between data points with NaN

From: Florin Neacsu

Date: 12 Apr, 2011 18:25:19

Message: 7 of 7

"Joe" wrote in message <io1vct$auh$1@fred.mathworks.com>...
> "John D'Errico" <woodchips@rochester.rr.com> wrote in message <inq8qs$64c$1@fred.mathworks.com>...
> > "Joe" wrote in message <inq238$qb2$1@fred.mathworks.com>...
> > > "John D'Errico" <woodchips@rochester.rr.com> wrote in message <inijrg$lra$1@fred.mathworks.com>...
> > > > "Joe" wrote in message <iniins$3h0$1@fred.mathworks.com>...
> > > > > I have some data points that I would like to interpolate between the sets.
> > > > > eg:
> > > > > y = [ 3 2 NaN 4 2 1 NaN NaN NaN 4 2 NaN 6];
> > > > > I want to find place an average between two numbers where there is a NaN and empty out the cases where there is more than one NaN value consecutively. For example, in the case above, y3 = NaN and I would like to replace y3 by (y2+y4)/2 and remove y7:y9.. etc.
> > > >
> > > > An option is inpaint_nans.
> > > >
> > > > y = [ 3 2 NaN 4 2 1 NaN NaN NaN 4 2 NaN 6];
> > > > inpaint_nans(y)
> > > > ans =
> > > > 3 2 3.1667 4 2 1 1.6 2.9 4 4 2 3.2 6
> > > >
> > > > Find it on the file exchange. It does something a little
> > > > more sophisticated than what you thought to do, but
> > > > who cares?
> > > >
> > > > http://www.mathworks.com/matlabcentral/fileexchange/4551
> > > >
> > > > John
> > >
> > > Thanks. This is good but I forgot to mention that I want to remove the places where there were two or more NaN consecutively. For example, the three NaNs that are between the 1 and the 4 are to be eliminated.
> >
> > Well, then remove them. Use the isnan function to flag
> > elements that are nan. Then find blocks of ones in
> > the result. For example, strfind can search for a pattern
> > in a vector. What will the locations of the substrings
> > [0 1] and [1 0] tell you in this respect? Note that these
> > substrings must alternate in a vector composed of only
> > 0 and 1 elements!
> >
> > Any blocks longer than your goal you will delete. At that
> > point, since you will have already found the singleton
> > nan elements, it is trivial to replace them with an average
> > of the neighbors.
> >
> > John
>
>
> Alright maybe it is because I am new to matlab. I have say:
> x = [4 NaN 2 4 2 NaN NaN 4 3]';
> x1 = x;
> k = isnan(x);
> for i = 2:length(x);
> if (x(i) == find(isnan(x),1,'first'))
> x1(i) = (x(i+1) + x(i-1))/2;
> elseif x(i) == find(isnan(x),2,'first'))
> x(i) = [ ];
> else
> x1(i) = x(i)
> end
> end
>
> What I would like to do is to determine if there is two or more NaN in consecutive order. If there is one, it removes them, else if there is a NaN between two numbers, it finds the average between the two numbers and replace the NaN with the average of the two numbers. Otherwise, the values remain the same.
>
> The result I am expected to get from the above is:
> x1 = [4 3 2 4 2 4 3];
>
> Thanks very much.

Hi,

This is a "mix" of all the above suggestions (Tideman and John's)

x = [4 NaN 2 4 4 2 NaN NaN NaN 4 3 NaN 1 2 NaN NaN 2]
%remove 2 or more consecutive NaN
b=isnan(x);
tt=b(1:end-1)& b(2:end);
tt2=circshift(tt,[0 -1]);
ttf=tt | tt2;
ttf=logical([0,ttf]);
x(ttf)=[]
% interpolate
bd=isnan(x);
gd=find(~bd);
x(bd)=interp1(gd,x(gd),find(bd));
x

I am sure there are more elegant ways to do it. Also, you should check and modify it for extreme cases : [Nan 2 3 ....] etc

Regards,
Florin
 

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us