Interpolate NaN values over a DataFrame as a ring

Viewed 213

I need to interpolate the NaN values over a Dataframe but I want that interpolation to get the first values of the DataFrame in case the NaN value is the last value. Here is an example:

import pandas as pd
import numpy as np
df = pd.DataFrame.from_dict({"a": [1,2,3], "b":[1,2,np.nan]})

So the DataFrame is:

   a    b
0  1  1.0
1  2  2.0
2  3  NaN

But when I interpolate the nan values like:

df.interpolate(method="linear", inplace=True)

I got:

   a    b
0  1  1.0
1  2  2.0
2  3  2.0

The interpolation doesn't use the first value to do it. My desired output wold be to fill in with the value of 1.5 because of that circular interpolation.

1 Answers

One possible solution is add first row, interpolate and remove last row:

df = df.append(df.iloc[0]).interpolate(method="linear").iloc[:-1]
print (df)
     a    b
0  1.0  1.0
1  2.0  2.0
2  3.0  1.5

EDIT:

More general solution:

df = pd.DataFrame.from_dict({"a": [1,2,3,4], "b":[np.nan,1,2,np.nan]})

df = pd.concat([df] * 3).interpolate(method="linear").iloc[len(df):-len(df)]

print (df)
   a         b
0  1  1.333333
1  2  1.000000
2  3  2.000000
3  4  1.666667

Or if need working only with last non missing values:

df = pd.DataFrame.from_dict({"a": [1,2,3,4], "b":[np.nan,1,2,np.nan]})

df1 = df.ffill().iloc[[-1]]
df2 = df.bfill().iloc[[0]]
df = pd.concat([df1, df, df2]).interpolate(method="linear").iloc[1:-1]

print (df)
   a    b
0  1  1.5
1  2  1.0
2  3  2.0
3  4  1.5
Related