使用两个掩码更新数组值a [mask1] [mask2] = value

时间:2015-09-23 12:37:16

标签: python arrays numpy

给定数组和掩码,我们可以为掩码中的TRUE位置分配新值:

import numpy as np    
a = np.array([1,2,3,4,5,6])
mask1 = (a==2) | (a==5)
a[mask1] = 100
print a
# [  1 100   3   4 100   6]

但是,如果我们在第一个掩码上应用第二个掩码,我们可以访问这些值,但我们无法修改它们:

a = np.array([1,2,3,4,5,6])
mask1 = (a==2) | (a==5)
mask2 = (a[mask1]==2)
print a[mask1][mask2]
# [2]
a[mask1][mask2] = 100
print a
# [ 1 2 3 4 5 6 ]

为什么会这样?

(即使这似乎是一种奇怪的方式。只是出于好奇)

2 个答案:

答案 0 :(得分:3)

这可能是因为您混合吸气剂 setters 阻止反向传播

这是因为您使用mark1作为索引器:

>>> mask1
array([False,  True, False, False,  True, False], dtype=bool)

现在通过设置a[mask1] = 100,您将设置mask1为真的所有元素,从而产生

>>> a
array([  1, 100,   3,   4, 100,   6])

请注意,您只是在a上发出了“设定者”的说法。

现在a[mask1][mask2] = 100你实际上称之为getter和setter。实际上你可以写成:

temp = a[mask1] #getter
temp[mask2] = 2#setter

因此您只在temp 中设置了值,因此该值不是“反向传播”,以便与{{1}对话本身。您应该将a视为副本(尽管在内部,python解释器可能会以不同的方式处理它)。

注意:请注意,在某种情况下,此行为可行:如果temp例如是阵列上的视图,则可能支持向后传播。例如This page显示了返回视图而不是副本的方法。

答案 1 :(得分:3)

您正在为分配链接advanced *索引操作,这会阻止将值100写回原始数组。

a[mask1]返回一个包含原始数据副本的新数组。编写a[mask1][mask2] = 100表示此 new 数组已编入mask2索引,并为其分配值100。这使a保持不变。

简单地查看项目似乎工作正常,因为您从副本a[mask1]中选择的值是您希望从原始数组中获取的值(尽管由于数据被多次复制,这仍然是低效的)。

使用布尔数组或索引数组触发

* 高级(或"花式")索引。它始终返回一个新数组,与basic indexing不同,后者将视图返回到原始数据(例如,通过切片触发)。