该解决方案重现了以下行为pd.Series.interpolate https://pandas.pydata.org/docs/reference/api/pandas.Series.interpolate.html使用默认参数。这不是一个适合初学者的解决方案,如果您的问题是家庭作业,我很想知道您的教授的期望是什么。
我正在使用具有前导、尾随和连续的数据框nan
价值观。我添加了一列带有插值的列来与我的解决方案进行比较。 ASeries
需要使用默认排序范围索引。
import pandas as pd
import numpy as np
np.random.seed(11)
a = np.where(np.random.rand(20) > .5, np.random.uniform(0,10, 20), np.nan)
df = pd.DataFrame({
'x': a
})
df['x_interp'] = df.x.interpolate()
df
Output
x x_interp
0 NaN NaN
1 NaN NaN
2 NaN NaN
3 3.187988 3.187988
4 NaN 2.661738
5 NaN 2.135487
6 NaN 1.609237
7 NaN 1.082987
8 0.556737 0.556737
9 4.797973 4.797973
10 4.016765 4.016765
11 NaN 5.597628
12 7.178492 7.178492
13 6.020641 6.020641
14 NaN 7.755832
15 9.491024 9.491024
16 NaN 9.491024
17 NaN 9.491024
18 NaN 9.491024
19 NaN 9.491024
该方法是找到具有nan
以及周围的价值观。然后用周围值之间的线性步长填充这些切片。这ffill
参数控制是否尾随nan
将用最后一个可用值填充。
def interp(ser, ffill=True):
ser = ser[df.x.notna().idxmax():].copy()
start = ser.notna() & ser.shift(-1, fill_value=0).isna()
end = ser.notna() & ser.shift(1, fill_value=0).isna()
for x,y in zip(ser.index[start],ser.index[end]):
step = (ser.loc[y] - ser.loc[x])/(y - x)
ser.loc[x:y] = [ser.loc[x] + i * step for i in range(y-x)] + [ser.loc[y]]
if ffill:
ser = ser.ffill()
return ser
df['x_new_interp'] = interp(df.x, False)
df['x_new_interp_ffill'] = interp(df.x)
df
Output
x x_interp x_new_interp x_new_interp_ffill
0 NaN NaN NaN NaN
1 NaN NaN NaN NaN
2 NaN NaN NaN NaN
3 3.187988 3.187988 3.187988 3.187988
4 NaN 2.661738 2.661738 2.661738
5 NaN 2.135487 2.135487 2.135487
6 NaN 1.609237 1.609237 1.609237
7 NaN 1.082987 1.082987 1.082987
8 0.556737 0.556737 0.556737 0.556737
9 4.797973 4.797973 4.797973 4.797973
10 4.016765 4.016765 4.016765 4.016765
11 NaN 5.597628 5.597628 5.597628
12 7.178492 7.178492 7.178492 7.178492
13 6.020641 6.020641 6.020641 6.020641
14 NaN 7.755832 7.755832 7.755832
15 9.491024 9.491024 9.491024 9.491024
16 NaN 9.491024 NaN 9.491024
17 NaN 9.491024 NaN 9.491024
18 NaN 9.491024 NaN 9.491024
19 NaN 9.491024 NaN 9.491024