插值-拉格朗日插值法

朗格朗日插值法的定義

原理

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

對比上面的多項式,能夠知道這個數組的元素就是上面多項式的係數!

拉格朗日插值法仍是比較好理解的,改天再總結一下其餘的插值法的寫法。

相關文章
相關標籤/搜索