Pandas与SciPy三次样条插值结果差异:是代码问题还是Bug?
Pandas与SciPy三次样条插值结果差异的原因
你的代码没有错误,也不是Pandas的Bug,差异源于两者底层使用的三次样条插值实现边界条件不同:
1. 底层实现的核心差异
- Pandas的
spline插值:在1.3.5版本中,df['values'].interpolate(method='spline', order=3)底层调用scipy.interpolate.UnivariateSpline,默认设置s=0(强制插值曲线通过所有已知数据点)。UnivariateSpline采用not-a-knot边界条件——强制端点处的三阶导数与相邻区间的三阶导数连续,避免端点出现过度波动。 - 你的SciPy实现:
interp1d(kind=3)本质调用scipy.interpolate.CubicSpline,采用自然边界条件——强制插值曲线在两端点的二阶导数为0,让曲线在端点处趋于平缓。
2. 验证结论的代码示例
模拟Pandas的插值结果
用UnivariateSpline手动实现,结果会和Pandas完全一致:
from scipy.interpolate import UnivariateSpline idx = df[~df['values'].isna()].index vals = df.loc[idx, 'values'] # 对应Pandas的参数:k=3(三次样条),s=0(强制过所有点) spline = UnivariateSpline(idx, vals, k=3, s=0) df['interpolated_univariate'] = spline(df.index)
模拟你用SciPy的插值结果
用CubicSpline手动实现,结果会和interp1d(kind=3)一致:
from scipy.interpolate import CubicSpline cs = CubicSpline(idx, vals, bc_type='natural') df['interpolated_cubic'] = cs(df.index)
3. 总结
两种插值结果都是合法的三次样条插值,只是边界条件的选择不同导致曲线形态有差异。如果需要让Pandas的结果和SciPy一致,可以手动指定使用CubicSpline实现插值,而非依赖Pandas内置的spline方法。
内容的提问来源于stack exchange,提问作者Raoul
相关产品推荐
相关产品推荐

