插值-拉格朗日插值法

朗格朗日插值法的定义

原理

通常地,若已知[]在互不相同 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应用

在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]

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

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

相关文章
相关标签/搜索