朗格朗日插值法的定义
原理
一般地,若已知[]在互不相同 n+1 个点[]处的函数值[]( 即该函数过[] 这n+1个点),则可以考虑构造一个过这n+1 个点的、次数不超过n的多项式[] ,使其满足:
[]
要估计任一点ξ,ξ≠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}。
满足插值条件的、次数不超过n的多项式是存在而且是唯一的。
定义
对某个多项式函数,已知有给定的k + 1个取值点: []
假设任意两个不同的x都互不相同,那么应用拉格朗日插值公式所得到的拉格朗日插值多项式为:
其中每个为拉格朗日基本多项式(或称插值基函数),其表达式为:
例子
例如:当n=4时,上面的公式可简化为:
这是一个过4个点的唯一的三次多项式。
个人体会
拉格朗日插值法用于补充缺失值,原理就是过N个点肯定会有一个多项式能满足条件,多项式次数最高是N-1(百度百科中的定义以N+1个数为样本,其实是一样的)。设多项式的每一项的x为(x0,x1……xN),则代入每一个点,就能得到多项式系数,也就能得到多项式。
个人感觉这种插值方法不会丢失数据信息,但是由于插值节点增减时,插值多项式会随之变化,实际上会影响效率,因此并不是比较推荐的插值方法(在小规模数据中可以使用)。
Python应用
在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]
对比上面的多项式,可以知道这个数组的元素就是上面多项式的系数!
拉格朗日插值法还是比较好理解的,改天再总结一下其他的插值法的写法。
来源:oschina
链接:https://my.oschina.net/u/4243370/blog/3190761