简体   繁体   English

双索引后更改数组元素

[英]Changing elements of array after double indexing

I have 2 logical arrays of unequal sizes (let's call bigger one b and smaller one c) and one which has numbers in it (array a).我有 2 个大小不等的逻辑数组(我们称之为较大的 b 和较小的 c)和一个其中包含数字的逻辑数组(数组 a)。 Size of the larger logical array is the same size as the array of numbers, while the size of smaller is equal to the sum of all truths in a bigger array.较大的逻辑数组的大小与数字数组的大小相同,而较小的逻辑数组的大小等于较大数组中所有真值的总和。 I want to change the element at index i only if b_i is jth truth and c_j is true.仅当 b_i 为第 j 个真值且 c_j 为真时,我才想更改索引 i 处的元素。
Sorry for a confusing explanation, but hopefully it will be clearer in code.对不起,解释混乱,但希望它在代码中更清晰。

In other words we would only check c if b was true, and index at which we check c is given by which truth in b it was.换句话说,如果 b 为真,我们只会检查 c,并且我们检查 c 的索引由 b 中的哪个真值给出。

I can create a tmp variable, which is of size c, and then apply c to it, but it makes my code really messy, which I would prefer to avoid.我可以创建一个大小为 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])

First print outputs [0, 4] , which is correct.首先打印输出[0, 4] ,这是正确的。 However, I expected second output to be an array of [2, 2 ], while it's [0, 4] again (similarly to third output, the workaround).但是,我希望第二个输出是[2, 2 ] 的数组,而它又是[0, 4] (类似于第三个输出,解决方法)。

Mask-the-mask approach蒙面方法

We can mask the first mask with itself while assigning into it the second one, so that only the True ones in the first one are changed according to the second mask.我们可以用它自己屏蔽第一个掩码,同时将第二个掩码分配给它,这样只有第一个掩码中的 True 会根据第二个掩码发生变化。 This sets up the first mask for boolean-indexing into the values array, like so -这为值数组中的布尔索引设置了第一个掩码,如下所示 -

b[b] = c # mask first mask with itself and assign second mask
a[b] = 2 # assign new value(s)

Note that it works with arrays.请注意,它适用于数组。

Sample run -样品运行 -

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

Alternative with Indices替代指数

An alternative would be using the indices of the True values in the first mask -另一种方法是在第一个掩码中使用 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])

I would go with the first one, for its memory-efficiency as boolean arrays have much lower memory footprint and moreover in this case, it's an in-situ edit into the already existing boolean array.我会选择第一个,因为它的内存效率高,因为布尔数组的内存占用要低得多,而且在这种情况下,它是对现有布尔数组的原位编辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM