scipy.interpolate 单变量插值

前言

1 数据预处理阶段,处理缺失值的方法分为三类,删除记录 数据插值 不处理,scipy提供了插值法的一些库接口,支持一维和多维(单变量和多元)插值类,Lagrange和Taylor多项式插值器等。本文解释一维插值法的几种python接口和使用案例(单变量插值)

2 一维插值的数据生成,主要有几个方式,生成多项式,用多项式预测未来值或者中间的值,使用导数/积分等数学上能让插值线性平滑(考虑多阶导数的平滑)的操作,来生成插值。几种出名的插值 拉格朗日插值、牛顿插值、分段线性插值、分段三次Hermite插值和样条插值(三次)

3 另外可以利用分段多项式,方便的给一维函数关系求n阶导数、n阶积分,定积分,求解方程

4 其它工具, lagrange插值、approximate_taylor插值、pade插值

参考:https://docs.scipy.org/doc/scipy/reference/interpolate.html
https://blog.csdn.net/ddjhpxs/article/details/105655394

目录

function name function inturation
interp1d(x, y[, kind, axis, copy, … ]) Interpolate a 1-D function.
BarycentricInterpolator(xi[, yi, axis]) The interpolating polynomial for a set of points
KroghInterpolator(xi, yi[, axis]) Interpolating polynomial for a set of points.
barycentric_interpolate(xi, yi, x[, axis]) Convenience function for polynomial interpolation.
krogh_interpolate(xi, yi, x[, der, axis ]) Convenience function for polynomial interpolation.
pchip_interpolate(xi, yi, x[, der, axis ]) Convenience function for pchip interpolation.
CubicHermiteSpline(x, y, dydx[, axis, … ]) Piecewise-cubic interpolator matching values and first derivatives.
PchipInterpolator(x, y[, axis, extrapolate ]) PCHIP 1-D monotonic cubic interpolation.
Akima1DInterpolator(x, y[, axis ]) Akima interpolator
CubicSpline(x, y[, axis, bc_type, extrapolate ]) Cubic spline data interpolator.
PPoly(c, x[, extrapolate, axis ]) Piecewise polynomial in terms of coefficients and breakpoints
BPoly(c, x[, extrapolate, axis ]) Piecewise polynomial in terms of coefficients and breakpoints.

interp1d

  • 功能描述:一维插值(分段线性插值),给定的 x 1d-array 和 y nd-array, 生成一个近似的映射函数f:y = f(x), 可以使用 ynew = f(xnew) 来生成插值数据.
  • 参数定义:scipy.interpolate.interp1d(x, y, kind='linear', axis=- 1, copy=True, bounds_error=None, fill_value=nan, assume_sorted=False)
  • 参数说明:
    • kind: 指定插值函数的数据生成线性特征 ‘linear’ ‘nearest’‘nearest-up’, ‘zero’, ‘slinear’, ‘quadratic’, ‘cubic’, ‘previous’, ‘next’
nearest   "snaps" to the nearest data point.
zero      is a zero order spline. It's value at any point is the last raw value seen.
linear    performs linear interpolation and slinear uses a first order spline. They use different code and can produce similar but subtly different results.
quadratic uses second order spline interpolation.
cubic     uses third order spline interpolation.


import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate as interpolate

np.random.seed(6)
kinds = ('nearest', 'zero', 'linear', 'slinear', 'quadratic', 'cubic')

N = 10
x = np.linspace(0, 1, N)
y = np.random.randint(10, size=(N,))

new_x = np.linspace(0, 1, 28)
fig, axs = plt.subplots(nrows=len(kinds)+1, sharex=True)
axs[0].plot(x, y, 'bo-')
axs[0].set_title('raw')
for ax, kind in zip(axs[1:], kinds):
    new_y = interpolate.interp1d(x, y, kind=kind)(new_x)
    ax.plot(new_x, new_y, 'ro-')
    ax.set_title(kind)

plt.show()
  • axis: 指定y轴哪个维度插值,默认是y的最后一维上
  • copy: 插值是引用还是拷贝
  • bounds_error: 如果为True,则任何时候尝试对x范围之外的值进行插值都会引发ValueError(在此情况下需要进行插值)。如果为False,则分配超出范围的值fill_value。默认情况下,除非引发错误fill_value="extrapolate"
  • fill_value: 用来指定填充值
  • assume_sorted: 如果为False,则x的值可以按任何顺序排列,并且将首先对其进行排序。如果为True,则x必须是单调递增值的数组。
  • 源码:
https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/interpolate.py#L329-L714
  • 试例:
import matplotlib.pyplot as plt
from scipy import interpolate
import numpy as np

x = np.arange(0, 10)
y = np.exp(-x/3.0)  # e的幂指数
f = interpolate.interp1d(x, y)

xnew = np.arange(0, 9, 0.1)
ynew = f(xnew)   # use interpolation function returned by `interp1d`
plt.plot(x, y, 'o', xnew, ynew, '-')
plt.show()
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
y
array([1.        , 0.71653131, 0.51341712, 0.36787944, 0.26359714,
       0.1888756 , 0.13533528, 0.09697197, 0.06948345, 0.04978707])
xnew
array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. , 1.1, 1.2,
       1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2. , 2.1, 2.2, 2.3, 2.4, 2.5,
       2.6, 2.7, 2.8, 2.9, 3. , 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8,
       3.9, 4. , 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 5. , 5.1,
       5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9, 6. , 6.1, 6.2, 6.3, 6.4,
       6.5, 6.6, 6.7, 6.8, 6.9, 7. , 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7,
       7.8, 7.9, 8. , 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, 8.9]
ynew
array([1.        , 0.97165313, 0.94330626, 0.91495939, 0.88661252,
       0.85826566, 0.82991879, 0.80157192, 0.77322505, 0.74487818,
       0.71653131, 0.69621989, 0.67590847, 0.65559705, 0.63528563,
       0.61497421, 0.5946628 , 0.57435138, 0.55403996, 0.53372854,
       0.51341712, 0.49886335, 0.48430958, 0.46975582, 0.45520205,
       0.44064828, 0.42609451, 0.41154074, 0.39698698, 0.38243321,
       0.36787944, 0.35745121, 0.34702298, 0.33659475, 0.32616652,
       0.31573829, 0.30531006, 0.29488183, 0.2844536 , 0.27402537,
       0.26359714, 0.25612498, 0.24865283, 0.24118068, 0.23370852,
       0.22623637, 0.21876422, 0.21129206, 0.20381991, 0.19634776,
       0.1888756 , 0.18352157, 0.17816754, 0.17281351, 0.16745947,
       0.16210544, 0.15675141, 0.15139738, 0.14604335, 0.14068932,
       0.13533528, 0.13149895, 0.12766262, 0.12382629, 0.11998996,
       0.11615363, 0.11231729, 0.10848096, 0.10464463, 0.1008083 ,
       0.09697197, 0.09422312, 0.09147426, 0.08872541, 0.08597656,
       0.08322771, 0.08047886, 0.07773001, 0.07498115, 0.0722323 ,
       0.06948345, 0.06751381, 0.06554417, 0.06357454, 0.0616049 ,
       0.05963526, 0.05766562, 0.05569598, 0.05372634, 0.05175671])

BarycentricInterpolator

https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/polyint.py#L497-L650
  • 试例:
import matplotlib.pyplot as plt
from scipy import interpolate
import numpy as np

x = np.array([1,2,3,4,5,6,7])
x = np.array([1,1.2,1.3,1.4,5,6,7])
y = np.array([1,3,5,7,4,2,1])

x = np.arange(0, 10)
y = np.exp(-x/3.0)  # e的幂指数

bci = interpolate.BarycentricInterpolator(x, y)   # create Barycentric interpolation object

x1 = np.arange(0.5, 9, 1)
y1 =  bci(x1)                                       # __call__(x) 
x2 = np.arange(0.9, 9, 1)
y2 =  bci(x2)

plt.plot(x, y, 'o', x1, y1, 'o', x2, y2, 'o') 
plt.show()

barycentric_interpolate

  • 功能描述:函数 重心插值法,给定的 x 1d-array 和 y nd-array, 和 BarycentricInterpolator实现原理一致, 由于重心插值计算相对较慢,若多次计算插值,应使用BarycentricInterpolator。
  • 参数定义:scipy.interpolate.barycentric_interpolate(xi, yi, x, axis=0)
  • 参数说明:
    • xi: 多项式应通过的点的x坐标的一维数组
    • yi: 多项式应通过的点的y坐标。
    • x: 要估计的点
    • axis: y中的维度
    • y: @return: 估计值
  • 源码:
https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/polyint.py#L653-L714
  • 试例:
import matplotlib.pyplot as plt
from scipy.interpolate import barycentric_interpolate
import numpy as np

x_observed = np.linspace(0.0, 10.0, 11)
y_observed = np.sin(x_observed)
x = np.linspace(min(x_observed), max(x_observed), num=100)
y = barycentric_interpolate(x_observed, y_observed, x)
plt.plot(x_observed, y_observed, "o", label="observation")
plt.plot(x, y, label="barycentric interpolation")
plt.legend()
plt.show()

KroghInterpolator

  • 功能描述:估值导数的插值法(克罗格插值),给定的 x 1d-array 和 y nd-array, 构造多项式.可估计某个点处的导数
  • 参数定义:scipy.interpolate.KroghInterpolator(xi, yi, axis=0)
  • 参数说明:
    • xi: 多项式应通过的点的x坐标的一维数组
    • yi: 多项式应通过的点的y坐标。
    • axis: y中的维度
    • call(self, x) 估值
    • derivative(self, x[, der]) 估计一个点处的导数
    • derivatives(self, x[, der]) 估计多个点处的导数
  • 源码:
https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/polyint.py#L220-L354
  • 试例:
import matplotlib.pyplot as plt
from scipy import interpolate
import numpy as np

x = np.arange(0, 10)
y = np.exp(-x/3.0)  # e的幂指数
# y = x / 3.0
ki = interpolate.KroghInterpolator(x, y)

x1 = np.arange(0.5, 9, 1)
y1 =  ki(x1)                                       # __call__(x) 
x2 = np.arange(0.9, 9, 1)
y2 =  ki(x2)

derivatives = ki.derivative(x1)
derivatives

plt.plot(x, y, 'o', x1, y1, 'o', x2, y2, 'o') 
plt.show()

krogh_interpolate

  • 功能描述:函数 估值导数的插值法,给定的 x 1d-array 和 y nd-array, 构造多项式.可估计某个点处的导数, 实现原理和KroghInterpolator一致

  • 参数定义:scipy.interpolate.krogh_interpolate(xi, yi, x, der=0, axis=0)

  • 参数说明:

    • xi: 多项式应通过的点的x坐标的一维数组
    • yi: 多项式应通过的点的y坐标。
    • x: 要计算的一个或多个点
    • der: 估值导数的阶数 ??
    • axis: y中的维度
    • d: @return: 估计的插值
  • 源码:

https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/polyint.py#L357-L420
  • 试例:
import matplotlib.pyplot as plt
from scipy.interpolate import krogh_interpolate
import numpy as np

x_observed = np.linspace(0.0, 10.0, 11)
y_observed = np.sin(x_observed)
x = np.linspace(min(x_observed), max(x_observed), num=100)
y = krogh_interpolate(x_observed, y_observed, x, [1,2,3,4,5])
plt.plot(x_observed, y_observed, "o", label="observation")
plt.plot(x, y[0], label="krogh derivative 1")
plt.plot(x, y[1], label="krogh derivative 2")
plt.plot(x, y[2], label="krogh derivative 3")
plt.plot(x, y[3], label="krogh derivative 4")
plt.plot(x, y[4], label="krogh derivative 5")
plt.legend()
plt.show()

PchipInterpolator

  • 功能描述:分段三次埃米尔特插值法,给定的 x 1d-array 和 y nd-array,

  • 参数定义:scipy.interpolate.PchipInterpolator(x, y, axis=0, extrapolate=None)

  • 参考: https://zhuanlan.zhihu.com/p/169664296

  • 参数说明:

    • xi: 一维数组,单调递增实数值。x不能包含重复值
    • yi: 一维实数数组。y沿插值轴的长度必须等于的长度x。如果是ND数组,用axis 参数选择正确的维度
    • axis: y中的维度
    • extrapolate: {bool, ‘periodic’, None}, 默认是True ,false决定是否根据两个边缘点来延伸, 'periodic' extrapolation 周期延伸
    • call(self, x[, nu, extrapolate]) Evaluate the piecewise polynomial or its derivative.
    • 估值这个分段多项式/或他的导数
    • derivative(self[, nu]) Construct a new piecewise polynomial representing the derivative.
    •  构造导数的分段多项式 返回一个 PPoly对象
      
    • antiderivative(self[, nu]) Construct a new piecewise polynomial representing the antiderivative.
    • 构造不定积分的分段多项式 返回一个 PPoly对象
    • roots(self[, discontinuity, extrapolate]) Find real roots of the the piecewise polynomial.
    • 构造原始的分段多项式
  • 源码:

https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/_cubic.py#L156-L299
  • 试例
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import PchipInterpolator as PCHIP
#PCHIP stands for Piecewise Cubic Hermite Interpolating Polynomial

x = [1,2,3,4,5,6]
y = [-1,-1,0,1,1,1]
pchip = PCHIP(x,y)
x_new = [2.5,3.5,4.5]
y_new = pchip.__call__(x_new) # y_new=pchip(x_new)
print(y_new)

pp_d = pchip.derivative()           # 导数的ppoly 对象
pp_anti_d = pchip.antiderivative()  # 不定积分的ppoly 对象
print(pchip.roots())                # 多项式的原式子 ndarray 表示

#同时执行两个plot,才能将两个图绘制到一个图上
plt.plot(x_new, y_new, 'ro')#插值点为红色圆点
plt.plot(x, y, 'b-')#原始点为蓝色线条
plt.show()

pchip_interpolate

  • 功能描述:pchip 插值法的便捷调用,给定的 x 1d-array 和 y nd-array

  • 参数定义:scipy.interpolate.pchip_interpolate(xi, yi, x, der=0, axis=0)

  • 参数说明:

    • xi: 多项式应通过的点的x坐标的一维数组
    • yi: 多项式应通过的点的y坐标。
    • x: 要计算的一个或多个点
    • der: 估值导数的阶数 ?? 默认0
    • axis: yi中的维度
    • y: @return 估计的插值
  • 源码:

https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/_cubic.py#L302-L360
  • 试例:
import matplotlib.pyplot as plt
from scipy.interpolate import pchip_interpolate
import numpy as np

x_observed = np.linspace(0.0, 10.0, 11)
y_observed = np.sin(x_observed)
x = np.linspace(min(x_observed), max(x_observed), num=100)
y = pchip_interpolate(x_observed, y_observed, x,[0,1,2,3])
plt.plot(x_observed, y_observed, "o", label="observation")
plt.plot(x, y[0], label="pchip der 0")
plt.plot(x, y[1], label="pchip der 1")
plt.plot(x, y[2], label="pchip der 2")
plt.plot(x, y[3], label="pchip der 3")
plt.legend()
plt.show()

Akima1DInterpolator

  • 功能描述:akima一维插值,The interpolation method by Akima uses a continuously differentiable sub-spline built from piecewise cubic polynomials. The resultant curve passes through the given data points and will appear smooth and natural.
    特点是插值显得尽可能使拟合曲线平滑自然

  • 参数定义:scipy.interpolate.Akima1DInterpolator(x, y, axis=0)

  • 参数说明:

    • xi: 一维数组,单调递增实数值。x不能包含重复值
    • yi: 一维实数数组。y沿插值轴的长度必须等于的长度x。如果是ND数组,用axis 参数选择正确的维度
    • axis: y中的维度
    • call(self, x[, nu, extrapolate]) Evaluate the piecewise polynomial or its derivative.
    • 估值这个分段多项式/或他的导数
    • derivative(self[, nu]) Construct a new piecewise polynomial representing the derivative.
    •  构造导数的分段多项式 返回一个 PPoly对象
      
    • antiderivative(self[, nu]) Construct a new piecewise polynomial representing the antiderivative.
    • 构造不定积分的分段多项式 返回一个 PPoly对象
    • roots(self[, discontinuity, extrapolate]) Find real roots of the the piecewise polynomial.
    • 构造原始的分段多项式
  • 源码:

https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/_cubic.py#L363-L461
  • 试例:
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import Akima1DInterpolator as Akima1D

#x = [1,2,3,4,5,6]
#y = [-1,-1,0,1,1,1]
x = np.arange(0, 10)
y = np.exp(-x/3.0)  # e的幂指数

akima = Akima1D(x,y)
x_new = [2.5,3.5,4.5]
y_new = akima.__call__(x_new)
print(y_new)

pp_d = akima.derivative()           # 导数的ppoly 对象
pp_anti_d = akima.antiderivative()  # 不定积分的ppoly 对象
print(akima.roots())                # 多项式的原式子 ndarray 表示

#同时执行两个plot,才能将两个图绘制到一个图上
plt.plot(x_new, y_new, 'ro')#插值点为红色圆点
plt.plot(x, y, 'b-')#原始点为蓝色线条
plt.show()

CubicHermiteSpline

  • 功能描述:Piecewise-cubic interpolator matching values and first derivatives.分段三次埃尔米特插值
    特点是可以指定每个观测点的一阶导数值,可以计算拟合多项式,积分多项式,导数多项式,可以求定积分

  • 参数定义:scipy.interpolate.CubicHermiteSpline(x, y, dydx, axis=0, extrapolate=None)

  • 参考:https://github.com/Galdeano/CubicHermiteSpline
       https://en.wikipedia.org/wiki/Cubic_Hermite_spline

  • 参数说明:

    • x: 多项式应通过的点的x坐标的一维数组
    • y: 多项式应通过的点的y坐标。长度和x一致
    • dydx: 每个点的导数, 长度和x一致
    • axis: y中的维度
    • extrapolate: {bool, ‘periodic’, None}, 默认是True ,false决定是否根据两个边缘点来延伸, 'periodic' extrapolation 周期延伸
    • call(self, x) 计算分段多项式的插值估值
    • derivative(self[, nu]) Construct a new piecewise polynomial representing the derivative.
    •  构造导数的分段多项式 返回一个 PPoly对象
      
    • antiderivative(self[, nu]) Construct a new piecewise polynomial representing the antiderivative.
    • 构造不定积分的分段多项式 返回一个 PPoly对象
    • integrate(self, a, b[, extrapolate]) Compute a definite integral over a piecewise polynomial.
    •  计算一个分段多项式的定积分 array-like
      
    • roots(self[, discontinuity, extrapolate]) Find real roots of the the piecewise polynomial.
    • 构造原始的分段多项式 ndarray
  • 源码:

https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/_cubic.py#L70-L153
  • 试例:
import matplotlib.pyplot as plt
import numpy as np
import scipy.interpolate 

x_observed = np.linspace(0.0, 10.0, 11)
y_observed = np.sin(x_observed)
dydx = np.linspace(5,5,11)    # 指定观测点的斜率、导数
# dydx = np.linspace(0,0,11)
chs = interpolate.CubicHermiteSpline(x_observed, y_observed, dydx, True, 'periodic') #周期外推

x = np.linspace(-3, 15, num=100)
y = chs.__call__(x)

plt.plot(x_observed, y_observed, "o", label="observation")
plt.plot(x, y, label="CubicHermiteSpline 0")

plt.legend()
plt.show()

pp_d = pchip.derivative()           # 导数的ppoly 对象
pp_anti_d = pchip.antiderivative()  # 不定积分的ppoly 对象
print(chs.integrate(3, 5))          # 计算定积分 
print(chs.roots())                  # 多项式的原式子 ndarray 表示

CubicSpline

  • 功能描述:三次样条数据插值器,给定的 x 1d-array 和 y nd-array, 构造多项式.可估计某个点处的导数

  • 参数定义:scipy.interpolate.CubicSpline(x, y, axis=0, bc_type='not-a-knot', extrapolate=None)

  • 参数说明:

    • x: 多项式应通过的点的x坐标的一维数组
    • y: 多项式应通过的点的y坐标。
    • axis: y中的维度
    • bc_type: 边界条件类型。需要两个附加的方程式(由边界条件给出)来确定每个线段上多项式的所有系数
    • “ not-a-knot”(默认):曲线末端的第一段和第二段是相同的多项式。当没有边界条件的信息时,这是一个很好的默认设置。
      ‘periodic’:假定插值函数是周期的周期性x[-1] - x[0]。 y的第一个和最后一个值必须相同:y[0] == y[-1]。这种边界条件将导致y'[0] == y'[-1]和y''[0] == y''[-1]。
      ‘clamped’:曲线末端的一阶导数为零。假设y为1Dbc_type=((1, 0.0), (1, 0.0))是相同的条件。
      ‘natural’:曲线末端的二阶导数为零。假设y为1Dbc_type=((2, 0.0), (2, 0.0))是相同的条件。
      如果bc_type是2元组,则第一个和第二个值将分别应用于曲线的起点和终点。元组值可以是前面提到的字符串之一(‘periodic’除外),也可以是元组(顺序为deriv_values),允许在曲线末端指定任意导数:
      ‘order’:导数阶1或2。
      ’deriv_value‘:数组包含微分值,形状必须与y相同,但不包括axis尺寸。例如,如果y是一维,那么deriv_value必须是标量。如果y是形状为(n0,n1,n2)且轴= 2的3D,则deriv_value必须是2D并具有形状(n0,n1)。
  • extrapolate: {bool, ‘periodic’, None}, 默认是True ,false决定是否根据两个边缘点来延伸, 'periodic' extrapolation 周期延伸

  • call(self, x) 计算分段多项式的插值估值

  • derivative(self[, nu]) Construct a new piecewise polynomial representing the derivative.

  •  构造导数的分段多项式 返回一个 PPoly对象
    
  • antiderivative(self[, nu]) Construct a new piecewise polynomial representing the antiderivative.

  • 构造不定积分的分段多项式 返回一个 PPoly对象

  • integrate(self, a, b[, extrapolate]) Compute a definite integral over a piecewise polynomial.

  •  计算一个分段多项式的定积分 array-like
    
  • roots(self[, discontinuity, extrapolate]) Find real roots of the the piecewise polynomial.

  • 构造原始的分段多项式 ndarray

  • 源码:

https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/_cubic.py#L464-L855
  • 试例:
from scipy.interpolate import CubicSpline
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10)
y = np.sin(x)
cs = CubicSpline(x, y)
xs = np.arange(-0.5, 9.6, 0.1)

fig, ax = plt.subplots(figsize=(6.5, 4))
ax.plot(x, y, 'o', label='data')
ax.plot(xs, np.sin(xs), label='true')
ax.plot(xs, cs(xs), label="S")        #  0 Order of derivative to evaluate
ax.plot(xs, cs(xs, 1), label="S'")    #  1 Order of derivative to evaluate
ax.plot(xs, cs(xs, 2), label="S''")   #  2 Order of derivative to evaluate
ax.plot(xs, cs(xs, 3), label="S'''")
ax.set_xlim(-0.5, 9.5)
ax.legend(loc='lower left', ncol=2)
plt.show()
from scipy.interpolate import CubicSpline
import numpy as np
import matplotlib.pyplot as plt

theta = 2 * np.pi * np.linspace(0, 1, 5)
y = np.c_[np.cos(theta), np.sin(theta)]
cs = CubicSpline(theta, y, bc_type='periodic')
print("ds/dx={:.1f} ds/dy={:.1f}".format(cs(0, 1)[0], cs(0, 1)[1]))

xs = 2 * np.pi * np.linspace(0, 1, 100)
fig, ax = plt.subplots(figsize=(6.5, 4))
ax.plot(y[:, 0], y[:, 1], 'o', label='data')
ax.plot(np.cos(xs), np.sin(xs), label='true')
ax.plot(cs(xs)[:, 0], cs(xs)[:, 1], label='spline')
ax.axes.set_aspect('equal')
ax.legend(loc='center')
plt.show()

PPoly

  • 功能描述:Piecewise polynomial in terms of coefficients and breakpoints 基于系数和断点的分段多项式.
    分段多项式的类定义, 对象可以表示一个分段多项式,通常可用于表示 CubicSpline CubicHermiteSpline PchipInterpolator 等插值多项式的一阶导数或者不定积分.
    一般不会直接创建对象, 会根据观测值的插值算法derivative、antiderivative来构造对象

  • 参数定义:scipy.interpolate.PPoly(c, x, extrapolate=None, axis=0)

  • 参数说明:

    • c: 多项式系数, order k and m intervals.
    • x: 多项式分段点, 一维数组,单调递增/递减实数值
    • axis: y中的维度
    • extrapolate: {bool, ‘periodic’, None}, 默认是True ,false决定是否根据两个边缘点来延伸, 'periodic' extrapolation 周期延伸
    • call(self, x[, nu, extrapolate]) Evaluate the piecewise polynomial or its derivative.
      计算多项式在 x处的值
    • derivative(self[, nu]) Construct a new piecewise polynomial representing the derivative.
      构造导函数的多项式 返回PPoly 对象
    • antiderivative(self[, nu]) Construct a new piecewise polynomial representing the antiderivative.
      构造不定积分的多项式  返回PPoly 对象
    • integrate(self, a, b[, extrapolate]) Compute a definite integral over a piecewise polynomial.
    • solve(self[, y, discontinuity, extrapolate]) Find real solutions of the the equation pp(x) == y.
      已知y,反解 pp(x) == y
    • roots(self[, discontinuity, extrapolate]) Find real roots of the the piecewise polynomial.
      返回分段多项式的系数数组
    • extend(self, c, x[, right]) Add additional breakpoints and coefficients to the polynomial.
      在分段多项式上增加分段点和系数
    • from_spline(tck[, extrapolate]) Construct a piecewise polynomial from a spline
    • from_bernstein_basis(bp[, extrapolate]) Construct a piecewise polynomial in the power basis from a polynomial in Bernstein basis.
    • construct_fast(c, x[, extrapolate, axis]) Construct the piecewise polynomial without making checks.
  • 源码:

https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/interpolate.py#L942-L1348
  • 试例:
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import PchipInterpolator as PCHIP

#x = [1,2,3,4,5,6]
#y = [-1,-1,0,1,1,1]
x = np.arange(0, 10)
y = np.exp(-x/3.0)  # e的幂指数

pchip = PCHIP(x,y)
x_new = [2.5,3.5,4.5]
y_new = pchip.__call__(x_new) # y_new=pchip(x_new)
print(y_new)

pp_x = np.arange(-2, 12, 0.3)

pp_d = pchip.derivative()           # 导数的ppoly 对象
pp_antid = pchip.antiderivative()  # 不定积分的ppoly 对象
y_ppd = pp_d(pp_x)
y_ppantid = pp_antid(pp_x)

#同时执行两个plot,才能将两个图绘制到一个图上
plt.plot(x_new, y_new, 'ro')#插值点为红色圆点
plt.plot(x, y, 'b-')#原始点为蓝色线条
plt.plot(pp_x, y_ppd, 'y-')#原始点为yellow线条
plt.plot(pp_x, y_ppantid, 'r-')#原始点为red线条
plt.show()

BPoly

The polynomial between x[i] and x[i + 1] is written in the Bernstein polynomial basis:

S = sum(c[a, i] * b(a, k; x) for a in range(k+1)),
where k is the degree of the polynomial, and:

b(a, k; x) = binom(k, a) * t**a * (1 - t)**(k - a),
with t = (x - x[i]) / (x[i+1] - x[i]) and binom is the binomial coefficient.
  • 参数说明:

    • c: 多项式系数, order k and m intervals.
    • x: 多项式分段点, 一维数组,单调递增/递减实数值
    • axis: y中的维度
    • extrapolate: {bool, ‘periodic’, None}, 默认是True ,false决定是否根据两个边缘点来延伸, 'periodic' extrapolation 周期延伸
    • call(self, x[, nu, extrapolate]) Evaluate the piecewise polynomial or its derivative.
      计算多项式在 x处的值
    • extend(self, c, x[, right]) Add additional breakpoints and coefficients to the polynomial.
      添加断点和系数
    • derivative(self[, nu]) Construct a new piecewise polynomial representing the derivative.
      构造导函数的多项式 返回 BPoly 对象
    • antiderivative(self[, nu]) Construct a new piecewise polynomial representing the antiderivative.
      构造不定积分的多项式  返回 BPoly 对象
    • integrate(self, a, b[, extrapolate]) Compute a definite integral over a piecewise polynomial.
      计算定积分
    • construct_fast(c, x[, extrapolate, axis]) Construct the piecewise polynomial without making checks.
      工厂方法, 与默认构造方法区别是不做检测
    • from_power_basis(pp[, extrapolate]) Construct a piecewise polynomial in Bernstein basis from a power basis polynomial.
      构造 PPoly 对象
    • from_derivatives(xi, yi[, orders, extrapolate]) Construct a piecewise polynomial in the Bernstein basis, compatible with the specified values and derivatives at breakpoints.
      工厂方法,用导数系数构造 BPoly 对象
  • 源码:

https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/interpolate.py#L1351-L1902
  • 试例:
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import BPoly

x = [0, 1]
c = [[1], [3], [1]]
bp = BPoly(c, x)

bp_x = np.arange(-3, 10, 0.1)
bp_y = bp(bp_x)

plt.plot(bp_x, bp_y, 'r-')#原始点为red线条
plt.show()

拉格朗日插值

https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/interpolate.py#L25-L82
  • 试例:
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import lagrange

x = np.array([0, 1, 2])
y = x**3
poly = lagrange(x, y)

lagrange_x = np.arange(-10, 10, 0.1)
lagrange_y = poly(lagrange_x)

plt.plot(lagrange_x, lagrange_y, 'r-')#原始点为red线条
plt.show()

泰勒多项式插值

  • 功能描述:近似泰勒多项式插值 给定两个一维数组x和w,返回通过点的拉格朗日插值多项式.

  • 参数定义:scipy.interpolate.approximate_taylor_polynomial(f, x, degree, scale, order=None)

  • 参考: https://numpy.org/devdocs/reference/generated/numpy.poly1d.html#numpy.poly1d

  • 参数说明:

    • f: 寻求泰勒多项式的函数。应该接受x值的向量.
    • x: 求多项式的点。
    • degree: 泰勒多项式的次数
    • scale: 拟合中使用的多项式的阶数;f将被评估order+1时间
    • return: numpy.poly1d实例
  • 源码:

https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/polyint.py#L423-L494
  • 试例:
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import approximate_taylor_polynomial

x = np.linspace(-10.0, 10.0, num=100)
plt.plot(x, np.sin(x), label="sin curve")

for degree in np.arange(1, 15, step=2):
    sin_taylor = approximate_taylor_polynomial(np.sin, 0, degree, 1,order=degree + 2)
    plt.plot(x, sin_taylor(x), label="degree={0}".format(degree))

plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left',borderaxespad=0.0, shadow=True)
plt.tight_layout()
plt.axis([-10, 10, -10, 10])
plt.show()

Pade

https://github.com/scipy/scipy/blob/v1.6.2/scipy/interpolate/_pade.py#L6-L65
  • 试例:
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import pade

e_exp = [1.0, 1.0, 1.0/2.0, 1.0/6.0, 1.0/24.0, 1.0/120.0]
p, q = pade(e_exp, 2)

e_exp.reverse()
e_poly = np.poly1d(e_exp)

e_poly(1)
p(1)/q(1)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容

  • 夜莺2517阅读 127,717评论 1 9
  • 版本:ios 1.2.1 亮点: 1.app角标可以实时更新天气温度或选择空气质量,建议处女座就不要选了,不然老想...
    我就是沉沉阅读 6,884评论 1 6
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,531评论 28 53
  • 兔子虽然是枚小硕 但学校的硕士四人寝不够 就被分到了博士楼里 两人一间 在学校的最西边 靠山 兔子的室友身体不好 ...
    待业的兔子阅读 2,593评论 2 9