Scipy 學習 第一篇:插補


scipy包提供了幾種通用的插補工具,分別用於1維,2維或高維的數據集,分別是:

  • 類 interp1d 用於對一維數據進行插補
  • 類 griddata 提供了對1D,2D和高維數據進行插補的工具。
  • spline插補, 用於對一維和二維數據進行平滑的cubic-spline 插補
  • 使用基於徑向的函數(RBF)進行插值

這些方法都集成在scipy.interpolate模塊中。

一,interp1d類

一維插補類(interp1d),是一種基於一維固定數據點創建函數的便捷方法,該函數內推一個一元的函數f,使得 y=f(x):

scipy.interpolate.interp1d(x, y, kind='linear', axis=-1, copy=True, bounds_error=None, fill_value=nan, assume_sorted=False)

kind 參數用於指定內推的類型,(‘linear’, ‘zero’, ‘slinear’, ‘quadratic’, ‘cubic’, ‘previous’, ‘next’和 ‘nearest’。對於'linear',是默認值,表示線性插補,前面已描述;對於 ‘zero’, ‘slinear’, ‘quadratic’ 和 ‘cubic’ 引用的是spline內推,使用 zeroth, first, second 和 third 順序。對於 ‘previous’ 、 ‘next’ 和  ‘nearest’ 簡單返回數據點的前一個、后一個或最近的一個數據。 

舉個例子,使用interp1d內推兩個函數,並繪制兩個函數插補的數據點:

>>> import scipy
>>> from scipy.interpolate import interp1d
>>> x = np.linspace(0, 10, num=11, endpoint=True)
>>> y = np.cos(-x**2/9.0)
>>> f = interp1d(x, y)
>>> f2 = interp1d(x, y, kind='cubic')
>>> xnew = np.linspace(0, 10, num=41, endpoint=True)
>>> import matplotlib.pyplot as plt
>>> plt.plot(x, y, 'o', xnew, f(xnew), '-', xnew, f2(xnew), '--')>>> plt.legend(['data', 'linear', 'cubic'], loc='best')
>>> plt.show()

二,多變量插補(griddata)

對於多維的數據,維度之間是相互關聯的,例如,age、education和income是相互關聯的,可以認為income = f(age,education)。對於二維數據,使用griddata 內推一個二元函數,z=f(x,y)。

scipy.interpolate.griddata(points, values, xi, method='linear', fill_value=nan, rescale=False)

參數注釋:

  • points:自變量,對於二元函數而言,points是指由(x,y)構成的數據點
  • values:因變量,values是指某一個數據點的值,對於二元函數而言,數據點(x,y)的值是z=f(x,y)
  • xi:坐標系,或者說是數據點在坐標系中的位置,也可以把points的值作為坐標系的x和y軸,把values作為坐標系的z軸
  • method:有效值是‘linear’, ‘nearest’, ‘cubic’

三,spline類

一維spline的處理過程分為兩個基本步驟:計算曲線的spline表示,對目標點進行評估。scipy有兩種方式來計算曲線的spline表示和平滑系數:直接方式和參數化方式。

1,直接方式

直接方式使用splrep()函數從2維平面中查找曲線的spline表示,x和y是曲線在二維坐標系中的坐標。

splrep()函數的作用是對於給定數據點集(x [i],y [i]),確定在間隔xb <= x <= xe上平滑度為k的近似值。

scipy.interpolate.splrep(x, y, w=None, xb=None, xe=None, k=3, task=0, s=None, t=None, full_output=0, per=0, quiet=1)

參數注釋:

  • x和y定義一個曲線,y=f(x)
  • w 權重,用於在spline擬合時計算加權最小二乘法的值,w的默認值為1/(len(x))。如果y值中的誤差是向量d給出的標准偏差,則w應為1 / d。
  • xb,xe:用於擬合的間隔,如果沒有指定,那么默認值分別是x[0] 和 x[-1]。
  • k  用於指定spline order,默認值是3,字符串表示為cubic,k的取值區間是[1,5]
  • s 用於制定平滑條件,滿足以下條件來確定平滑度:sum((w *(y-g))** 2,axis = 0)<= s,其中g(x)是(x,y)的平滑插值。 用戶可以使用s來控制貼合度和平滑度之間的權衡,較大的s表示更平滑,而較小的s值表示較不平滑。s的推薦值取決於權重w。 如果權重代表y的標准偏差的倒數,則應在(m-sqrt(2 * m),m + sqrt(2 * m))范圍內找到一個好的s值,其中m是 x,y和w中的數據點。 默認值:如果提供了權重,則s = m-sqrt(2 * m)。 如果未提供權重,則s = 0.0(內插)。

該函數輸出的結果是一個三元組tck,這個三元組就是曲線的spline表示,用於表示曲線的節點向量、系數和spline序號,默認的spline orde是cubic,這可以通過k參數來修改。一旦確定了曲線的spline表示,就可以使用splev()函數對x進行評估:

scipy.interpolate.splev(x, tck, der=0, ext=0)

舉個例子,使用splrep()函數來獲取曲線的spline表示,也就是tck,再通過tck和splev()函數來評估曲線:

>>> import matplotlib.pyplot as plt
>>> from scipy.interpolate import splev, splrep
>>> x = np.linspace(0, 10, 10)
>>> y = np.sin(x)
>>> spl = splrep(x, y)
>>> x2 = np.linspace(0, 10, 200)
>>> y2 = splev(x2, spl)
>>> plt.plot(x, y, 'o', x2, y2)
>>> plt.show()

2,參數化方式

對於在N維空間中的區間,使用函數splprep()來定義曲線的參數:

scipy.interpolate.splprep(x, w=None, u=None, ub=None, ue=None, k=3, task=0, s=None, t=None, full_output=0, nest=None, per=0)

參數注釋:

  • x:代表N維空間中曲線的N個數組的列表,每個數組的長度都是曲線的點的數量,每一個數組都提供N維數據點的一個分量。
  • u:是參數值的數組,該參數默認為0到1之間的等距單調序列,計算公式是:

M = len(x[0]), where v[0] = 0
v[i] = v[i-1] + distance(x[i], x[i-1])
u[i] = v[i] / v[M-1]

  • ub,ue:參數間隔的端點,默認值是 u [0]和u [-1]。
  • k:spline擬合的度,推薦使用默認值k=3,表示cubic,k的取值區間是[1,5]
  • s:平滑度,是0到1之間的小數,0表示不平滑,值越大,平滑度越高。
  • per:如果非0,那么把數據點視為周期性曲線,周期為x [m-1]-x [0],並返回平滑的周期樣條近似。

默認輸出包含兩個對象:第一個對象是一個三元祖(t,c,k),分別表示曲線的節點向量、系數和spline序號;第二個對象是一個參數變量u。

 

對於函數splprep() 返回的spline表示,使用splev()函數來評估

>>> from scipy.interpolate import splprep, splev
>>> tck, u = splprep([x, y], s=0)
>>> new_points = splev(u, tck)
>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> ax.plot(x, y, 'ro')
>>> ax.plot(new_points[0], new_points[1], 'r-')
>>> plt.show()

 

 

 

 

 

參考文檔:

SciPy documentation

SciPy tutorial.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM