双索引后更改数组元素

时间:2019-08-14 05:28:13

标签: python numpy

我有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](类似于第三种输出,解决方法)。

1 个答案:

答案 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])

我会选择第一个,因为它的内存效率很高,因为布尔数组的内存占用量要低得多,而且在这种情况下,它是对现有布尔数组的原位编辑。