如何在修改旧值的情况下在 pandas 中使用 `Series.interpolate`
How to use `Series.interpolate` in pandas with the old values modified
pandas
中的 interploate
方法使用有效数据对 nan
值进行插值。但是,它保持旧的有效数据不变,如下代码。
有没有什么方法可以使用 interploate
方法更改旧值,使序列变得平滑?
In [1]: %matplotlib inline
In [2]: from scipy.interpolate import UnivariateSpline as spl
In [3]: import numpy as np
In [4]: import pandas as pd
In [5]: samples = { 0.0: 0.0, 0.4: 0.5, 0.5: 0.9, 0.6: 0.7, 0.8:0.3, 1.0: 1.0 }
In [6]: x, y = zip(*sorted(samples.items()))
In [7]: df1 = pd.DataFrame(index=np.linspace(0, 1, 31), columns=['raw', 'itp'], dtype=float)
In [8]: df1.loc[x] = np.array(y)[:, None]
In [9]: df1['itp'].interpolate('spline', order=3, inplace=True)
In [10]: df1.plot(style={'itp': 'b-', 'raw': 'rs'}, figsize=(8, 6))
In [11]: df2 = pd.DataFrame(index=np.linspace(0, 1, 31), columns=['raw', 'itp'], dtype=float)
In [12]: df2.loc[x, 'raw'] = y
In [13]: f = spl(x, y, k=3)
In [14]: df2['itp'] = f(df2.index)
In [15]: df2.plot(style={'itp': 'b-', 'raw': 'rs'}, figsize=(8, 6))
当您将 Series.interpolate
与 method='spline'
一起使用时,在后台 Pandas 使用
interpolate.UnivariateSpline
.
返回的样条
UnivariateSpline
不能保证通过作为输入给出的数据点除非
s=0
。
但是,默认情况下 s=None
,它使用不同的平滑因子,因此会导致不同的结果。
Series.interpolate
方法总是填充NaN
值
不改变非 NaN 值。没有办法使
Series.interpolate
修改非 NaN 值。所以,当s != 0
时,结果
产生锯齿状跳跃。
所以如果你想要 s=None
(默认)样条插值但没有
锯齿状的跳跃,正如您已经发现的,您必须调用 UnivariateSpline
直接覆盖 df['itp']
:
中的所有值
df['itp'] = interpolate.UnivariateSpline(x, y, k=3)(df.index)
如果你想要一个通过所有非 NaN 数据点的三次样条,那么
使用 s=0
df['itp'].interpolate('spline', order=3, s=0, inplace=True)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy.interpolate as interpolate
samples = { 0.0: 0.0, 0.4: 0.5, 0.5: 0.9, 0.6: 0.7, 0.8:0.3, 1.0: 1.0 }
x, y = zip(*sorted(samples.items()))
fig, ax = plt.subplots(nrows=3, sharex=True)
df1 = pd.DataFrame(index=np.linspace(0, 1, 31), columns=['raw', 'itp'], dtype=float)
df1.loc[x] = np.array(y)[:, None]
df2 = df1.copy()
df3 = df1.copy()
df1['itp'].interpolate('spline', order=3, inplace=True)
df2['itp'] = interpolate.UnivariateSpline(x, y, k=3)(df2.index)
df3['itp'].interpolate('spline', order=3, s=0, inplace=True)
for i, df in enumerate((df1, df2, df3)):
df.plot(style={'itp': 'b-', 'raw': 'rs'}, figsize=(8, 6), ax=ax[i])
plt.show()
pandas
中的 interploate
方法使用有效数据对 nan
值进行插值。但是,它保持旧的有效数据不变,如下代码。
有没有什么方法可以使用 interploate
方法更改旧值,使序列变得平滑?
In [1]: %matplotlib inline
In [2]: from scipy.interpolate import UnivariateSpline as spl
In [3]: import numpy as np
In [4]: import pandas as pd
In [5]: samples = { 0.0: 0.0, 0.4: 0.5, 0.5: 0.9, 0.6: 0.7, 0.8:0.3, 1.0: 1.0 }
In [6]: x, y = zip(*sorted(samples.items()))
In [7]: df1 = pd.DataFrame(index=np.linspace(0, 1, 31), columns=['raw', 'itp'], dtype=float)
In [8]: df1.loc[x] = np.array(y)[:, None]
In [9]: df1['itp'].interpolate('spline', order=3, inplace=True)
In [10]: df1.plot(style={'itp': 'b-', 'raw': 'rs'}, figsize=(8, 6))
In [11]: df2 = pd.DataFrame(index=np.linspace(0, 1, 31), columns=['raw', 'itp'], dtype=float)
In [12]: df2.loc[x, 'raw'] = y
In [13]: f = spl(x, y, k=3)
In [14]: df2['itp'] = f(df2.index)
In [15]: df2.plot(style={'itp': 'b-', 'raw': 'rs'}, figsize=(8, 6))
当您将 Series.interpolate
与 method='spline'
一起使用时,在后台 Pandas 使用
interpolate.UnivariateSpline
.
返回的样条
UnivariateSpline
不能保证通过作为输入给出的数据点除非
s=0
。
但是,默认情况下 s=None
,它使用不同的平滑因子,因此会导致不同的结果。
Series.interpolate
方法总是填充NaN
值
不改变非 NaN 值。没有办法使
Series.interpolate
修改非 NaN 值。所以,当s != 0
时,结果
产生锯齿状跳跃。
所以如果你想要 s=None
(默认)样条插值但没有
锯齿状的跳跃,正如您已经发现的,您必须调用 UnivariateSpline
直接覆盖 df['itp']
:
df['itp'] = interpolate.UnivariateSpline(x, y, k=3)(df.index)
如果你想要一个通过所有非 NaN 数据点的三次样条,那么
使用 s=0
df['itp'].interpolate('spline', order=3, s=0, inplace=True)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy.interpolate as interpolate
samples = { 0.0: 0.0, 0.4: 0.5, 0.5: 0.9, 0.6: 0.7, 0.8:0.3, 1.0: 1.0 }
x, y = zip(*sorted(samples.items()))
fig, ax = plt.subplots(nrows=3, sharex=True)
df1 = pd.DataFrame(index=np.linspace(0, 1, 31), columns=['raw', 'itp'], dtype=float)
df1.loc[x] = np.array(y)[:, None]
df2 = df1.copy()
df3 = df1.copy()
df1['itp'].interpolate('spline', order=3, inplace=True)
df2['itp'] = interpolate.UnivariateSpline(x, y, k=3)(df2.index)
df3['itp'].interpolate('spline', order=3, s=0, inplace=True)
for i, df in enumerate((df1, df2, df3)):
df.plot(style={'itp': 'b-', 'raw': 'rs'}, figsize=(8, 6), ax=ax[i])
plt.show()