插值-拉格朗日插值法

独自空忆成欢 提交于 2020-03-09 23:42:14

朗格朗日插值法的定义

原理

一般地,若已知[]在互不相同 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]

对比上面的多项式,可以知道这个数组的元素就是上面多项式的系数!

拉格朗日插值法还是比较好理解的,改天再总结一下其他的插值法的写法。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!