Python 当一个数据类型是对象时,numpy掩码数组的行为不同

Python 当一个数据类型是对象时,numpy掩码数组的行为不同,python,arrays,numpy,masking,recarray,Python,Arrays,Numpy,Masking,Recarray,假设我有以下两个掩码数组声明: arr1 = ma.array([(1,2,"hello"),(10,20,"world!")],dtype=[("p1",int),("p2",float),("p3",object)]) arr1.mask["p1"][0] = True arr1.mask["p2"][1] = True arr2 = ma.array([(1,2,3),(10,20,30)],dtype=[("p1",int),("p2",float),("p3",int)]) arr2

假设我有以下两个掩码数组声明:

arr1 = ma.array([(1,2,"hello"),(10,20,"world!")],dtype=[("p1",int),("p2",float),("p3",object)])
arr1.mask["p1"][0] = True
arr1.mask["p2"][1] = True

arr2 = ma.array([(1,2,3),(10,20,30)],dtype=[("p1",int),("p2",float),("p3",int)])
arr2.mask["p1"][0] = True
arr2.mask["p2"][1] = True
正如您所看到的,唯一(轻微?)的区别是“p3”字段是
arr1
的对象,是
arr2
的int

调用
arr2[0]
是可以的,并给出
(-2.0,3)

但是,当屏蔽
arr1
的某些元素时,调用
arr1[0]
会产生以下错误:

***ValueError:使用缓冲区设置对象成员的void数组。

显然,将一个字段声明为对象会引发一些麻烦,但我不知道为什么

您对此有何看法?请记住,我确实需要通过这种方式访问“arr1[0]”,您是否会看到一些规避此问题的方法

非常感谢

埃里克


编辑:numpy版本<1.8时出现此问题。我尝试了最新版本(1.8),它还可以。

当您创建这样的数组时,为每个
dtype
字段或使用属性访问其字段的数组命名

因此,要访问
arr1
的第一个字段,您应该执行以下操作:

arr1['p1']
#masked_array(data = [-- 10],
#             mask = [ True False],
#       fill_value = 999999)
而不是
arr1[0]


编辑:二维解决方案类似于:

b1m = np.array([[True, False, False],[False, True, False]])
b1 = np.ma.array([[1, 2, 'hello'],
                  [10, 20, 'world!']], mask=b1m, dtype=object)
b2m = np.array([[True, False, False],[False, True, False]])
b2 = np.ma.array([[1, 2, 3],
                  [10, 20, 30]], mask=b2m, dtype=object)

我发现这个问题发生在numpy版本<1.8时。我尝试了最新的版本(1.8),它是确定的。所以我想我不得不接受这个


谢谢您的帮助。

谢谢您的反馈。然而,我仍然不明白,当其中一个字段是对象时,为什么构造失败。此外,在我的项目中,我确实需要通过
arr1[0]
@PellegriniEric对我的屏蔽数组进行行访问。问题是
recarray
不是二维数组,因此您无法访问
a[I,j]
之类的项,它是一组一维数组,每个数组按其字段名调用。你可以重新设计你的代码来处理二维数组……对于上面给出的例子,什么是替代设计呢?请记住,我希望保留蒙面数组功能,以非常通用的方式处理我的数据库中缺少/无效值的问题?@PellegriniEric我已经更新了一种可能性的答案对于二维阵列解决方案…谢谢。不幸的是,这个设计不适合我的问题,因为它会认为所有的东西都是一个难以跟踪无效条目的对象。这就是为什么我在寻找一些方法来声明一个包含多个数据类型的数组,而不给每个数据类型分配标签