gpt4 book ai didi

python - 结构化数组的掩码是否应该自行结构化?

转载 作者:行者123 更新时间:2023-12-01 04:52:14 25 4
gpt4 key购买 nike

我正在调查numpy issue 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

如果我以不同的方式创建掩码数组,则掩码数据类型的结构类似于数组本身的数据类型:

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 不是结构化的?

换句话来说:是numpy.ma.core.MaskedArray中的__repr____getitem__方法中的错误,还是真正的错误之前发生过的错误 - 通过允许这样一个掩码结构化数组存在?

最佳答案

第一种情况中的错误表明这些方法期望掩码具有与基本数组相同的字段数量(和名称)

__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', '?')])

换句话说,每个元素的每个字段都有一个掩码值。

masked_array文档显然打算将“相同形状”包括 dtype结构。 Mask: Must be convertible to an array of booleans with the same shape as 'data'.

如果我尝试以与 masked_where 相同的方式设置掩码确实

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

我遇到同样的打印错误。结构化掩码被新的 bool 值覆盖,从而更改其数据类型。相反,如果我使用

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

Rn打印效果很好。 .mask是一个属性,其 set方法显然可以正确处理结构化掩码。

在不深入研究代码历史记录(在 github 上)的情况下,我的猜测是 masked_where是一个便利函数,当结构数据类型添加到 ma 的其他部分时,该函数不会更新。代码。与ma.masked_array相比这是一个简单的函数,根本不考虑数据类型。其他便利功能,如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返回简单的“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对于非结构化数值数组仍然有用,同时防止误用到结构化数组。

我还应该看看测试代码。

关于python - 结构化数组的掩码是否应该自行结构化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28182408/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com