通常地,若已知[]在互不相同 n+1 个点[
]处的函数值[
]( 即该函数过[
] 这n+1个点),则能够考虑构造一个过这n+1 个点的、次数不超过n的多项式[
] ,使其知足:python
[]数组
要估计任一点ξ,ξ≠xi,i=0,1,2,...,n,则能够用Pn(ξ)的值做为准确值f(ξ)的近似值,此方法叫作“插值法”。函数
称式(*)为插值条件(准则),含xi(i=0,1,...,n)的最小区间[a,b],其中a=min{x0,x1,...,xn},b=max{x0,x1,...,xn}。3d
知足插值条件的、次数不超过n的多项式是存在并且是惟一的。excel
对某个多项式函数,已知有给定的k + 1个取值点: []code
假设任意两个不一样的x都互不相同,那么应用拉格朗日插值公式所获得的拉格朗日插值多项式为:
其中每一个为拉格朗日基本多项式(或称插值基函数),其表达式为:
blog
例如:当n=4时,上面的公式可简化为:
这是一个过4个点的惟一的三次多项式。ip
拉格朗日插值法用于补充缺失值,原理就是过N个点确定会有一个多项式能知足条件,多项式次数最高是N-1(百度百科中的定义以N+1个数为样本,实际上是同样的)。设多项式的每一项的x为(x0,x1……xN),则代入每个点,就能获得多项式系数,也就能获得多项式。ci
我的感受这种插值方法不会丢失数据信息,可是因为插值节点增减时,插值多项式会随之变化,实际上会影响效率,所以并非比较推荐的插值方法(在小规模数据中可使用)。文档
在Python中,主要用scipy.interpolate(interpolate就是插值的意思)中的lagrange函数来实现 先来看看官方文档: scipy.interpolate.lagrange(x, w) 该函数会返回一个拉格朗日插值多项式,参数是x和w,两个一维数组,经过这两个参数返回多项式。 另外注意,这个函数是数值不稳定的,最好一次性不要取超过20个元素(数组里建议不要超过20个元素)
参数
x:表明的是点中的x轴,是一个数组
w:表明的是y轴,也就是f(x),一样也是一个数组
返回值
返回一个numpy.poly1d 的实例(用来表示多项式的类)
在scipy.interpolate.lagrange(x, w)后面加(a),表明的意思是,返回插值里面的第a个值,直接返回的是插值
import pandas as pd import matplotlib.pyplot as plt import numpy as np from scipy.interpolate import lagrange #拉格朗日插值 df = pd.read_excel(r"missing_data.xls", header=None) def lagrange_interpolate(s, n, k=5):#拉格朗日插值法函数 w = s[list(range(n-k, n)) + list(range(n+1, n+k+1))]#取前5个,后5个的元素为w, index是x w = w[w.notnull()]#拉格朗日插值中的w不能为空! print(lagrange(w.index, list(w)))#直接输出拉格朗日插值多项式 print(lagrange(w.index, list(w)).c)#输出拉格朗日多项式的参数 return lagrange(w.index, list(w))(n)#输出x为n的时候,插入的推导值 for i in df.columns: for j in range(len(df)): if (df.iloc[:,i].isnull())[j]:#把为空的值取出来(第i列中Nan为True的,第j行) df[i][j] = lagrange_interpolate(df.iloc[:,i], j)#把插值赋给原DataFrame print(df)
输出获得的df以下:
0 1 2 0 235.833300 324.034300 478.323100 1 236.270800 325.637900 515.456400 2 238.052100 328.089700 517.090900 3 235.906300 203.462116 514.890000 4 236.760400 268.832400 493.352591 5 237.151181 404.048000 486.091200 6 237.416700 391.265200 516.233000 7 238.656300 380.824100 493.342382 8 237.604200 388.023000 435.350800 9 238.031300 206.434900 487.675000 10 235.072900 237.348072 609.193564
输出的lagrange(w.index, list(w))
以下:
7 6 5 4 3 2
-0.2173 x + 6.261 x - 70.84 x + 396 x - 1125 x + 1484 x - 689.3 x + 324
上面的数字表明次数,MarkDown不太会排版哈哈哈
输出的lagrange(w.index, list(w)).c
以下:
[-2.17348599e-01 6.26122790e+00 -7.08415701e+01 3.96049765e+02 -1.12466918e+03 1.48430174e+03 -6.89281036e+02 3.24034300e+02]
对比上面的多项式,能够知道这个数组的元素就是上面多项式的系数!
拉格朗日插值法仍是比较好理解的,改天再总结一下其余的插值法的写法。