python - 无法修改屏蔽数组中的数据。 arr[i] 与 arr.data[i]

标签 python arrays numpy

在修改屏蔽数组中的数据时,我没想到会出现以下行为。似乎可以使用 [] 操作数修改某些值,但不是全部。但是,如果您访问其数据属性,则可以修改所有内容。仅当元组中单元格的掩码中有 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')])

最佳答案

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

当您使用时(按需要工作)

arr.data[1][1]=5

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

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

arr[1][1]=5

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

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

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

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

这整个复制与 View 的事情是 numpy 的一个非常经典的陷阱。为了公平地对待开发人员,考虑到 __getitem__() 必须如何对屏蔽数组起作用(即,在读取值时它必须返回屏蔽副本),我不确定他们如何解决它。但看看是否有人比我更聪明,也许值得花一张 bug 票。

关于python - 无法修改屏蔽数组中的数据。 arr[i] 与 arr.data[i],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19179677/

相关文章:

python - 如何禁用 Gtk 上的所有默认按键

java - 如何返回最右边的正数数组切割?

python - numpy 中的并行数组操作

arrays - 将数组切片为反向重叠的子数组

c++ - 连接一系列 std::arrays

python - 绘制 numpy 数组 : setting axis scale

python - popen 没有正确转发 args - Python

c# - 在 64 位上没有修改权限的情况下,从 UNC 路径加载 .Net 程序集失败

python - Kivy:App.root 中的实例无效

ios - 生成非重复随机数的 Swift 数组