2

在修改掩码数组中的数据时,我没想到会出现以下行为。似乎可以使用 [] 操作数修改某些值,但不是全部。但是,如果您访问它的数据属性,那么您可以修改所有。仅当元组中的单元格的掩码中有 True 值时才会发生这种情况(与掩码数组相关的所有操作似乎都正常工作)。

谁能解释为什么?

>>> import numpy as np
>>> import numpy.ma as ma
>>> arr = ma.ones(nrows, dtype=[('c1', np.int),('c2', np.int)])
>>> arr.mask[1][0] = True
>>> arr[1][1] = 3
>>> arr[0][0] = 4
>>> arr
masked_array(data = [(4, 1) (--, 1) (1, 1)],
         mask = [(False, False) (True, False) (False, False)],
   fill_value = (999999, 999999),
        dtype = [('c1', '<i8'), ('c2', '<i8')])

>>> arr.data[1][1]=5
>>> arr
masked_array(data = [(4, 1) (--, 5) (1, 1)],
         mask = [(False, False) (True, False) (False, False)],
   fill_value = (999999, 999999),
        dtype = [('c1', '<i8'), ('c2', '<i8')])
4

2 回答 2

3

我相信这是一个错误。这是正在发生的事情。

当您使用时(根据需要工作)

arr.data[1][1]=5

使用该函数_get_data()并返回底层 nparray 的简单视图。

当您使用时(工作不正常)

arr[1][1]=5

使用该功能__getitme__()。首先,它进入并尝试抓取第 1 行。它检测到该行上的一个项目被屏蔽并返回该行的屏蔽副本(而不是数组的视图)。根本问题在于 ma\core.py 的这一行(当前在github上的版本的第 2996 行):

dout = mvoid(dout, mask=mask, hardmask=self._hardmask)

mvoid 函数返回第 1 行的副本(其中包括 value 的掩码[1][0])而不是第 1 行的视图。然后处理列索引时,它正在对副本而不是视图进行更改。

为什么这适用于不包含掩码的行是返回视图而不是movid()副本。

整个副本与查看的事情是 numpy 的一个非常经典的问题。为了对开发人员公平起见,考虑到__getitem__()掩码数组必须如何工作(即,在读取值时它必须返回一个掩码副本),我不确定他们如何解决这个问题。但可能值得一张错误票,看看是否有比我更聪明的人有一个想法。

于 2013-10-04T13:27:26.430 回答
2

文档中没有将 getterarr[i][j]列为访问数据的正确方法。它提供了其他 4 种方法,我尝试了其中的 3 种:

>>> import numpy as np
>>> arr = np.ma.ones(3, dtype=[('c1', np.int),('c2', np.int)])
>>> arr.mask[0][1] = arr.mask[1][1] = arr.mask[2][1]= True
>>> arr.data[0][0] = 2              # data attribute
>>> np.ma.getdata(arr)[1][0] = 3    # ma.getdata function
>>> arr.__array__()[2][0] = 4       # __array__() method
>>> print(arr)
[(2, --) (3, --) (4, --)]
于 2013-10-04T13:26:34.323 回答