插值,是依據一系列的點(xi,yi)通過一定的算法找到一個合適的函數來包含(逼近)這些點,反應出這些點的走勢規律,然后根據走勢規律求其他點值的過程。
scipy.interpolate包里有很多類可以實現對一些已知的點進行插值,即找到一個合適的函數,例如,interp1d類,當得到插值函數后便可用這個插值函數計算其他xj對應的的yj值了,這也就是插值的意義所在。
一維插值interp1d
interp1d類可以根據輸入的點,創建擬合函數。
准備數據
讓我們首先創建一些點,作為輸入:
示例
通過采樣幾個點獲取數據:
import numpy as np from scipy import interpolate as intp import matplotlib.pyplot as plt x = np.linspace(0, 4, 12) y = np.cos(x**2/3 + 4) print (x) print (y)
輸出
[0. 0.36363636 0.72727273 1.09090909 1.45454545 1.81818182
2.18181818 2.54545455 2.90909091 3.27272727 3.63636364 4. ]
[ 0.28366219 0.29287074 0.35652484 0.52035398 0.78524277 0.99671469
0.70096272 -0.43008856 -0.87804302 0.84953035 -0.4614798 0.4979562 ]
讓我們畫出這些點:
plt.plot(x, y,’o’)
plt.show()
interp1d 插值
根據上面示例中的數據,使用interp1d類創建擬合函數:
f1 = intp.interp1d(x, y, kind = 'linear') f2 = intp.interp1d(x, y, kind = 'cubic')
上面創建了兩個函數f1和f2。通過這些函數,輸入x可以計算y。kind
表示插值使用的技術類型,例如:’Linear’, ‘Nearest’, ‘Zero’, ‘Slinear’, ‘Quadratic’, ‘Cubic’等等。
現在,增加輸入數據,與前面示例比較一下:
xnew = np.linspace(0, 4, 30) plt.plot(x, y, 'o', xnew, f1(xnew), '-', xnew, f2(xnew), '--') plt.legend(['data', 'linear', 'cubic','nearest'], loc = 'best') plt.show()
上面的程序將生成以下輸出:
噪聲數據插值
可以通過interpolate模塊中UnivariateSpline類對含有噪聲的數據進行插值運算。
使用UnivariateSpline類,輸入一組數據點,通過繪制一條平滑曲線來去除噪聲。繪制曲線時可以設置平滑參數s,如果參數s=0,將對所有點(包括噪聲)進行插值運算,也就是說s=0時不去除噪聲。
示例
import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import UnivariateSpline x = np.linspace(-3, 3, 50) y = np.exp(-x**2) + 0.1 * np.random.randn(50) # 通過random方法添加噪聲數據 plt.plot(x, y, 'ro', ms=5) # 平滑參數使用默認值 spl = UnivariateSpline(x, y) xs = np.linspace(-3, 3, 1000) plt.plot(xs, spl(xs), 'b', lw=3) # 藍色曲線 # 設置平滑參數 spl.set_smoothing_factor(0.5) plt.plot(xs, spl(xs), 'g', lw=3) # 綠色曲線 # 設置平滑參數為0 spl.set_smoothing_factor(0) plt.plot(xs, spl(xs), 'yellow', lw=3) # 黃色曲線 plt.show()
輸出