我有2个大小不等的逻辑数组(我们称其较大的一个b和较小的一个c的数组),其中一个具有数字(数组a)。较大逻辑数组的大小与数字数组的大小相同,而较小逻辑数组的大小等于较大数组中所有真值的总和。我只想在b_i是第j个真值且c_j是true的情况下才更改索引i的元素。
抱歉,造成混乱的解释,但希望代码中的解释会更清楚。
换句话说,我们只会检查b是否为真,而检查c的索引由b中的真值给出。
我可以创建一个大小为c的tmp变量,然后将c应用于它,但这会使我的代码非常混乱,我希望避免。
import numpy as np
a = np.arange(6)
b = [True, False, True, False, True, False]
c = [True, False, True]
print(a[b][c])
a[b][c] = 2
print(a[b][c])
# Messy workaround
tmp = a[b]
tmp[c] = 2
a[b] = tmp
print(a[b][c])
第一次打印输出[0, 4]
是正确的。但是,我希望第二个输出是[2, 2
的数组,而它又是[0, 4]
(类似于第三种输出,解决方法)。
答案 0 :(得分:1)
遮罩方法
我们可以自己屏蔽第一个掩码,同时将第二个掩码分配给它,以便仅根据第一个掩码更改第一个掩码中的True。这样就为将布尔值索引到values数组中的第一个掩码设置了,像这样-
b[b] = c # mask first mask with itself and assign second mask
a[b] = 2 # assign new value(s)
请注意,它适用于数组。
样品运行-
In [48]: a = np.arange(6)
...: b = np.array([True, False, True, False, True, False])
...: c = np.array([True, False, True])
In [49]: a
Out[49]: array([0, 1, 2, 3, 4, 5])
In [50]: b
Out[50]: array([ True, False, True, False, True, False])
# Mask the first mask with itself and assign the second one into it
In [51]: b[b] = c
# Verify the new mask
In [52]: b
Out[52]: array([ True, False, False, False, True, False])
# Index values array with it and assign new value(s)
In [53]: a[b] = 2
# Verify edited values array
In [54]: a
Out[54]: array([2, 1, 2, 3, 2, 5])
替代索引
一种替代方法是在第一个掩码中使用True值的索引-
In [59]: a = np.arange(6)
...: b = np.array([True, False, True, False, True, False])
...: c = np.array([True, False, True])
In [60]: idx = np.flatnonzero(b)
In [61]: a[idx[c]] = 2
In [62]: a
Out[62]: array([2, 1, 2, 3, 2, 5])
我会选择第一个,因为它的内存效率很高,因为布尔数组的内存占用量要低得多,而且在这种情况下,它是对现有布尔数组的原位编辑。