第一种情况中的错误表明这些方法期望掩码具有与基本数组相同的字段数量(和名称)
__getitem__: dout._mask = _mask[indx]
_recursive_printoption: (curdata, curmask) = (result[name], mask[name])
如果掩码数组是使用“main”构造函数创建的,则掩码具有相同的结构
Rn = np.ma.masked_array(R, mask=R['A']>5)
Rn.mask.dtype: dtype([('A', '?'), ('B', '?')])
换句话说,每个元素的每个字段都有一个掩码值。
The masked_array
医生显然打算将“相同形状”包括在内dtype
结构。Mask: Must be convertible to an array of booleans with the same shape as 'data'.
如果我尝试以相同的方式设置蒙版masked_where
does
Rn._mask=R['A']>5
我得到同样的打印错误。结构化掩码被新的布尔值覆盖,从而更改其数据类型。相反,如果我使用
Rn.mask=R['A']<5
Rn
打印效果很好。.mask
是一个属性,其set
方法显然可以正确处理结构化掩模。
如果不深入研究代码历史(在 github 上),我的猜测是masked_where
是一个便利函数,当结构数据类型添加到结构的其他部分时,该函数不会更新ma
代码。相比ma.masked_array
这是一个简单的函数,根本不考虑数据类型。其他便利功能,例如ma.masked_greater
use masked_where
。改变result._mask = cond
to result.mask = cond
可能是纠正此问题所需的全部内容。
您对非结构化掩模的后果进行了多彻底的测试?
Rm.flatten()
返回一个带有结构化掩码的数组,即使它以非结构化掩码开头。那是因为它使用Rm.__setmask__
,对字段敏感。这就是set
函数为mask
财产。
Rm.tolist() # same error as str()
masked_where
以。。开始:
cond = make_mask(condition)
make_mask
返回简单的“bool”数据类型。也可以使用 dtype 调用它,生成结构化掩码:np.ma.make_mask(R['A']<5,dtype=R.dtype)
。但这种结构化掩模在使用时会变平masked_where
. masked_where
不仅允许非结构化掩码,而且还强制其非结构化。
您的非结构化掩码已经部分实现,recordmask
财产:
recordmask = property(fget=_get_recordmask)
我说部分是因为它有一个get
方法,但是set
方法尚未实现。看def _set_recordmask(self):
我越看这个就越确信masked_where
是错的。它可以更改为设置结构化掩码,但它与masked_array
。如果在构造数组时引发错误(有dtype.names
)。那样masked_where
对于非结构化数值数组仍然有用,同时防止误用到结构化数组。
我还应该看看测试代码。