通常地,若已知[]在互不相同 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]
對比上面的多項式,能夠知道這個數組的元素就是上面多項式的係數!
拉格朗日插值法仍是比較好理解的,改天再總結一下其餘的插值法的寫法。