应该结构化阵列的面具被自身结构?(Is the mask of a structured array

2019-10-21 16:48发布

我一直在寻找到numpy的问题2972和几个相关的问题。 事实证明,所有这些问题都涉及到在阵列本身的结构的情况,但它的面具是不是:

In [38]: R = numpy.zeros(10, dtype=[("A", "<f2"), ("B", "<f4")])

In [39]: Rm = numpy.ma.masked_where(R["A"]<5, R)

In [41]: Rm.dtype
Out[41]: dtype([('A', '<f2'), ('B', '<f4')])

In [42]: Rm.mask.dtype
Out[42]: dtype('bool')

# Now, both `__getitem__` and `__repr__` will result in errors — see issue #2972

如果我不同的创建一个屏蔽数组,面具D型的结构类似于数组本身的D型:

In [44]: Q.dtype
Out[44]: dtype([('A', '<f4'), ('B', '<f4')])

In [45]: Q.mask.dtype
Out[45]: dtype([('A', '?'), ('B', '?')])

在前一种情况下暴露出一些问题。 例如, Rm.__repr__()Rm["A"]都导致IndexError ,虽然这是一个ValueError过去。

在设计上,是模式应该是可能的,其中A.dtype的结构,但A.mask.dtype不规整?

换句话说:在错误__repr____getitem__的方法numpy.ma.core.MaskedArray ,或是前发生的真实的错误-通过允许这样的掩蔽结构化阵列中的第一个地方存在?

Answer 1:

在第一种情况下的错误表示方法期望面膜具有字段相同的编号(和名称)为基阵

__getitem__:  dout._mask = _mask[indx]
_recursive_printoption: (curdata, curmask) = (result[name], mask[name])

如果被屏蔽的阵列是使与“主”构造,掩模具有相同的结构

Rn = np.ma.masked_array(R, mask=R['A']>5)
Rn.mask.dtype: dtype([('A', '?'), ('B', '?')])

换句话说,对于每个元件的每个字段中的掩码值。

masked_array DOC显然有意对“相同的形状”包括dtype结构。 Mask: Must be convertible to an array of booleans with the same shape as 'data'.

如果我尝试设置的面具同样的方式, masked_where

Rn._mask=R['A']>5

我得到同样的打印错误。 该结构化的掩模获取与新的布尔覆盖,改变它的D型。 相反,如果我使用

Rn.mask=R['A']<5

Rn打印精细。 .mask是一个属性,它的set方法显然能够正确地处理结构化的掩模。

没有挖掘到的历史记录码(在github上)我的猜测是, masked_where是当结构dtypes添加到其他地区,这不是更新了方便的功能ma代码。 相比于ma.masked_array这是一个简单的函数,不会在D型看所有。 其他方便的功能,如ma.masked_greater使用masked_where 。 更改result._mask = condresult.mask = cond可能是所有这一切都需要纠正这个问题。


如何彻底你测试非结构化面具的后果是什么?

Rm.flatten()

返回一个数组具有结构化的掩模,甚至当它开始与非结构化之一。 这是因为它采用Rm.__setmask__ ,这是场很敏感。 而这是set为功能mask性能。

Rm.tolist()  # same error as str()

masked_where开头:

cond = make_mask(condition)

make_mask返回简单的“布尔” D型。 它也可以用一个D型调用,产生结构化的掩模: np.ma.make_mask(R['A']<5,dtype=R.dtype) 但在使用时,这种结构化的掩模被夷为平地masked_wheremasked_where不仅允许一个非结构化的面具,它迫使它是非结构化的。

非结构化面具已经部分实现,该recordmask属性:

recordmask = property(fget=_get_recordmask)

我说,部分原因是它有一个get方法,但set方法尚未实现。 见def _set_recordmask(self):

我越是看这更我相信masked_where是错误的。 它可以改变设置结构化的掩模,但那就不是从很多不同的masked_array 。 它可能会更好,如果它引发错误当阵列的结构(具有dtype.names )。 这样masked_where仍将是非结构化数字数组非常有用,同时防止误用结构化的。

我还应该看一下测试代码。



文章来源: Is the mask of a structured array supposed to be structured itself?