为3D阵列创建布尔蒙版

时间:2019-06-22 15:16:24

标签: python numpy scipy

我有一个3D numpy数组,大小为[2000x7200x40](我们称它为precip),我想屏蔽掉某些要排除在scipy.mstats.rankdata(precip,axis=2,use_missing=False)分类中的值(-9999)。

请考虑以下数据:

[-9999, 2, 3, 5, -9999
       4, 7, -9999, 6]...

我在很大程度上没有成功;似乎大多数np.ma函数(例如np.ma.masked_invalid仅适用于一维数组)。

对于时间序列(z)中的每个数组,

-9999值可能不同。

我尝试了numpy函数,例如:

 #mask the -9999 values out
   mask = np.empty_like(precip)
   mask = ~(precip == -9999).all(axis=2,keepdims=True)

然后使用mask = [numpy.newaxis,:,:]

将其广播到3-D阵列中

但是,这将导致一个2000x7200x1数组,该数组乘以precip时会引发尺寸错误,因为它期望的是尺寸为40的数组。

是否有一些我忽略的简单功能或一些代码可以轻松地对我做到这一点?感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

您绝对可以使用蒙版的多维数组。但是,必须确保掩码和数据大小相同。

>>> mask = ~(precip == -9999).all(axis=2, keepdims=True)
>>> mask.shape
(2000, 7200, 1)
>>> repeated_mask = np.repeat(mask, precip.shape[-1], axis=-1) # Ensure same shape
>>> repeated_mask.shape == precip.shape
True
>>> ma = np.ma.masked_array(precip, mask=repeated_mask)
>>> ma.shape == precip.shape
True

请注意,只要不使用np.newaxis添加 additional 轴,也可以将掩码乘以原始数据数组而不会出现问题。 keepdims=True的{​​{1}}参数表示维数相同,因此由于Numpy's broadcasting机制,np.all可以直接乘以mask。例如:

precip

答案 1 :(得分:0)

因此,我最终完全放弃了mstats排名方法;当整行明显被掩盖时,它会避免。

我最终使用了上面的屏蔽代码:        mask = ~(precip == -9999).all(axis=2, keepdims=True)

apply_along_axis(lambda a: scipy.stats.ranking(a), axis=2, precip))方法之后

然后ranks = ranks*mask就能掩盖降水数据中始终为-9999的值。

希望这可以帮助那些对mstats.ranking感到困惑的人日后吐出0维数组错误。 scipy.stats.ranking模块似乎比scipy.mstats.ranking模块要快得多。