[英]Python/Scipy 2D Interpolation (Non-uniform Data)
這是我上一篇文章的后續問題: Python / Scipy Interpolation(map_coordinates)
假設我想在2d矩形區域上進行插值。 我的變量'z'包含如下所示的數據。 每列都是一個常量值,但是,數組的每一行可能處於不同的值,如下面的注釋所示。
from scipy import interpolate
from numpy import array
import numpy as np
# # 0.0000, 0.1750, 0.8170, 1.0000
z = array([[-2.2818,-2.2818,-0.9309,-0.9309], # 0.0000, 0.0000, 0.0000, 0.0000
[-2.2818,-2.2818,-0.9309,-0.9309], # 0.2620, 0.2784, 0.3379, 0.3526
[-1.4891,-1.4891,-0.5531,-0.5531], # 0.6121, 0.6351, 0.7118, 0.7309
[-1.4891,-1.4891,-0.5531,-0.5531]]) # 1.0000, 1.0000, 1.0000, 1.0000
# Rows, Columns = z.shape
cols = array([0.0000, 0.1750, 0.8170, 1.0000])
rows = array([0.0000, 0.2620, 0.6121, 1.0000])
sp = interpolate.RectBivariateSpline(rows, cols, z, kx=1, ky=1, s=0)
xi = np.array([0.00000, 0.26200, 0.27840, 0.33790, 0.35260, 0.61210, 0.63510,
0.71180, 0.73090, 1.00000], dtype=np.float)
yi = np.array([0.000, 0.167, 0.815, 1.000], dtype=np.float)
print sp(xi, yi)
作為另一種可視化方法,我知道的值數組將是:
rows = array([0.0000, 0.2620, 0.2784, 0.3379, 0.3526,
0.6121, 0.6351, 0.7118, 0.7309, 1.0000])
# # 0.0000, 0.1750, 0.8170, 1.0000
z = array([[-2.2818,-2.2818,-0.9309,-0.9309], # 0.0000
[-2.2818, ?, ?, ?], # 0.2620,
[ ?,-2.2818, ?, ?], # 0.2784
[ ?, ?,-0.9309, ?], # 0.3379
[ ? ,?, ?,-0.9309], # 0.3526
[-1.4891, ?, ?, ?], # 0.6121
[ ?,-1.4891, ?, ?], # 0.6351
[ ?, ?,-0.5531, ?], # 0.7118
[ ?, ?, ?,-0.5531], # 0.7309
[-1.4891,-1.4891,-0.5531,-0.5531]]) # 1.0000
我不知道'?' 值,它們應該插值。 我嘗試用None替換它們,但是對於我的所有結果都得到'nan'。
編輯:
我想我需要使用'griddata'或'interp2'。 griddata似乎產生了我期望的結果,但'interp2'卻沒有。
from scipy import interpolate
from numpy import array
import numpy as np
z = array([[-2.2818,-2.2818,-0.9309,-0.9309],
[-2.2818,-2.2818,-0.9309,-0.9309],
[-1.4891,-1.4891,-0.5531,-0.5531],
[-1.4891,-1.4891,-0.5531,-0.5531]])
rows = array([0.0000, 0.0000, 0.0000, 0.0000,
0.2620, 0.2784, 0.3379, 0.3526,
0.6121, 0.6351, 0.7118, 0.7309,
1.0000, 1.0000, 1.0000, 1.0000])
cols = array([0.0000, 0.1750, 0.8180, 1.0000,
0.0000, 0.1750, 0.8180, 1.0000,
0.0000, 0.1750, 0.8180, 1.0000,
0.0000, 0.1750, 0.8180, 1.0000])
xi = array([0.0000, 0.2620, 0.2784, 0.3379, 0.3526, 0.6121, 0.6351, 0.7118,
0.7309, 1.0000], dtype=np.float)
yi = array([0.000, 0.175, 0.818, 1.000], dtype=np.float)
GD = interpolate.griddata((rows, cols), z.ravel(),
(xi[None,:], yi[:,None]), method='linear')
I2 = interpolate.interp2d(rows, cols, z, kind='linear')
print GD.reshape(4, 10).T
print '\n'
print I2(xi, yi).reshape(4, 10).T
import matplotlib.pyplot as plt
import numpy.ma as ma
plt.figure()
GD = interpolate.griddata((rows.ravel(), cols.ravel()), z.ravel(),
(xi[None,:], yi[:,None]), method='linear')
CS = plt.contour(xi,yi,GD,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,GD,15,cmap=plt.cm.jet)
plt.colorbar()
plt.scatter(rows,cols,marker='o',c='b',s=5)
plt.figure()
I2 = I2(xi, yi)
CS = plt.contour(xi,yi,I2,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,I2,15,cmap=plt.cm.jet)
plt.colorbar()
plt.scatter(rows,cols,marker='o',c='b',s=5)
plt.show()
看起來你明白了。
在您的上層代碼示例和之前( 鏈接 )的問題中,您有結構化數據。 可以使用RectBivariateSpline
或interp2d
進行插值。 這意味着您可以在網格上描述數據(網格上的所有點都具有已知值)。 網格不一定必須具有相同的dx和dy。 (如果所有dx和dy都相等,你就會有一個Regular Grid)
現在,您當前的問題詢問如果不知道所有要點該怎么做。 這稱為非結構化數據。 你所擁有的只是一個領域的精選點。 您不一定要構造所有頂點都具有已知值的矩形。 對於這種類型的數據,您可以使用(如您所示) griddata
或BivariateSpline
的風格。
現在選哪個?
與結構化RectBivariateSpline
最接近的類比是非結構化 BivariateSpline
類之一 : SmoothBivariateSpline
或LSQBivariateSpline
。 如果要使用樣條線來插入數據,請使用這些。 這使得您的功能平滑且可微分,但您可以獲得一個在Z.max()或Z.min()之外擺動的曲面。
由於你設置ky=1
和kx=1
並且得到我非常肯定的結構化數據的線性插值,我個人只是從RectBivariateSpline
樣條方案切換到interp2d
結構化網格插值方案。 我知道文檔說它適用於常規網格 ,但__doc__
本身的例子只是結構化的 ,而不是常規的。
如果您在最終切換時發現方法之間存在任何顯着差異,我會很好奇。 歡迎來到SciPy。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.