我想插入內容掩蓋數據的二維數組。我已經使用了一些SciPy模塊的可用方法,包括interp2d
,bisplrep/bisplev
以及RectBivariateSpline
。作爲附加信息,我的數據是一個常規數組,這意味着網格具有相同的尺寸(在此情況下爲1ºX1º)。帶掩碼數據的Scipy插值?
話雖如此,是否有任何方法來插入避免與Python數組中的屏蔽數據?我仍然使用Python和NumPy/SciPy模塊。
我想插入內容掩蓋數據的二維數組。我已經使用了一些SciPy模塊的可用方法,包括interp2d
,bisplrep/bisplev
以及RectBivariateSpline
。作爲附加信息,我的數據是一個常規數組,這意味着網格具有相同的尺寸(在此情況下爲1ºX1º)。帶掩碼數據的Scipy插值?
話雖如此,是否有任何方法來插入避免與Python數組中的屏蔽數據?我仍然使用Python和NumPy/SciPy模塊。
實際上,您可以使用每個接受x, y, z
(這是interp2d以及其他可能的情況)的函數與您的掩碼數據。但是,你需要明確創建mgrid
:
z = ... # Your data
x, y = np.mgrid[0:z.shape[0], 0:z.shape[1]]
然後,你需要刪除所有這些座標的所有蒙面值:
x = x[~z.mask]
y = y[~z.mask]
z = z[~z.mask]
有了這些最終x, y, z
你可以調用每一個你指定的功能(接受不完整的網格,所以RectBivariateSpline
將無法正常工作)。但請注意,其中一些使用插值框,因此如果由於掩碼而丟棄數據的區域太大,則插值將在那裏失敗(導致np.nan
或0)。但是如果發生這種情況,你可能會調整參數來彌補這一點。
data = np.random.randint(0, 10, (5,5))
mask = np.random.uniform(0,1,(5,5)) > 0.5
z = np.ma.array(data, mask=mask)
x, y = np.mgrid[0:z.shape[0], 0:z.shape[1]]
x1 = x[~z.mask]
y1 = y[~z.mask]
z1 = z[~z.mask]
interp2d(x1, y1, z1)(np.arange(z.shape[0]), np.arange(z.shape[1]))
array([[ 1.1356716 , 2.45313727, 3.77060294, 6.09790177, 9.31328935],
[ 3.91917937, 4. , 4.08082063, 3.98508121, 3.73406764],
[ 42.1933738 , 25.0966869 , 8. , 0. , 0. ],
[ 1.55118338, 3. , 4.44881662, 4.73544593, 4. ],
[ 5. , 8. , 11. , 9.34152525, 3.58619652]])
可以看到0的小區域,因爲面膜必須有很多蒙面值:
mask
array([[False, True, True, True, False],
[False, False, True, False, False],
[ True, True, False, True, True],
[False, True, False, True, True],
[False, True, False, False, True]], dtype=bool)
data
array([[2, 4, 4, 5, 5],
[1, 4, 1, 3, 8],
[9, 1, 8, 0, 9],
[7, 2, 0, 3, 4],
[9, 6, 0, 4, 4]])
您的方法很有趣。我嘗試使用我的實際數據運行一個函數[如您的示例中所示]。但是,正如你所提到的,大型蒙面區域轉換爲0。就我而言,'0'很重要,因爲我正在處理溫度和降水的氣候數據。因此,插值後我不能刪除或屏蔽這些0。非常感謝你! – hurrdrought
只看着MSeifert的代碼,我不知道爲什麼會發生。如果'零'是一個問題,你可以使用'np.fill'來填充任意任意可識別數字的掩碼,例如-9999左右。 – roadrunner66
@ roadrunner66 - 樣條插值對異常值非常敏感,所以用某些明確的異常值填充值不是很有效。 – MSeifert
我通常遵循@mseifert描述的方法,但增加如果我厭倦了通過蒙版區域的插值誤差,下面的細化。這似乎是你的擔心之一,@hurrdrought?這個想法是將掩碼傳播給插值結果。一維數據的一個簡單例子是:
def ma_interp(newx,x,y,mask,propagate_mask=True):
newy = np.interp(newx,x[~mask],y[~mask]) # interpolate data
if propagate_mask: # interpolate mask & apply to interpolated data
newmask = mask[:]
newmask[mask] = 1; newmask[~mask] = 0
newmask = np.interp(newx,x,newmask)
newy = np.ma.masked_array(newy, newmask>0.5)
return newy
其實我並不認爲有很多插值忽略屏蔽數據。至少不是像numpy,scipy這樣的標準庫。我總是寫下我自己的接受面具的功能。對於一維數據,至少可以用掩碼(''x = x [〜y.mask]''和'y = y [〜y')掩蓋''x''和''y''。掩碼]''),但是因爲這使得n維數據不可能的數組變平。 – MSeifert
如何製作只包含未屏蔽數據的數組副本? (例如'ma.filled')。既然現在你的數組不再是一個完整的網格,你不能使用'RectBivariateSpline',但是'interp2d'仍然可以工作。你只需要將每個點指定爲x,y,z,這樣你就不得不在numpy的幫助下生成那些輸入數據。 – roadrunner66
許多'ma'知道函數使用'filled'來創建一個臨時副本。例如'ma.sum'使用'filled(0)'來替換被無害0的掩碼值。在插值情況下什麼是無害的價值? – hpaulj