![](/img/trans.png)
[英]Ignore specific values in scipy's interpolation (NaN, masked, zero …)
[英]Scipy interpolation with masked data?
我试图插入一个内容掩盖数据的2D数组。 我使用了一些SciPy模块的方法,包括interp2d
, bisplrep/bisplev
,以及RectBivariateSpline
。 作为附加信息,我的数据是一个常规数组,这意味着网格具有相同的尺寸(在这种情况下为1ºX1º)。
话虽如此,有没有办法用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]])
@MSeifert概述的方法的问题在于规则网格结构丢失,导致插值效率低。 仅通过插值填充缺失数据是合理的,但不适用于从一个网格到另一个网格的典型插值,其中不应填充缺失数据。
在这种情况下,使用np.nan填充缺失值是最简单的方法。 这些将在计算中传播,并且只要缺失值用于插值,结果数组将具有nans。
# fast interpolator that use the regular grid structure (x and y are 1D arrays)
z = z_masked.filled(np.nan)
zinterp = RegularGridInterpolator((x, y), z.T)
# new grid to interpolate on
X2, Y2 = np.meshgrid(x2, y2)
newpoints = np.array((X2, Y2)).T
# actual interpolation
z2 = zinterp(newpoints)
z2_masked = np.ma.array(z2, mask=np.isnan(z2))
为了完整性,另一种方法是插入第二个mask
阵列(填充1,其中缺少数据)以填充新网格上的缺失值。
# fast interpolator that use the regular grid structure (x and y are 1D arrays)
zinterp = RegularGridInterpolator((x, y), z.T)
minterp = RegularGridInterpolator((x, y), (mask+0.).T)
# actual interpolation
z2 = zinterp(newpoints)
mask2 = minterp(newpoints) > 0 # apply threshold, e.g. 0.5 is considered contaminated and will be removed.
z2[mask2] = np.nan # fill with nans or whatever missing data flag
请注意,如果需要样条曲线插值,这两种方法也应该适用于RectBivariateSpline。 无论哪种方式,这应该比使用interp2d快得多......
我通常遵循@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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.