给定数组和掩码,我们可以为掩码中的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 ]
为什么会这样?
(即使这似乎是一种奇怪的方式。只是出于好奇)
答案 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不同,后者将视图返回到原始数据(例如,通过切片触发)。