我想将数组arr_2
的值分配给另一个数组arr_1
。但是,我想基于2个选择标准来执行此操作。作为一个工作示例,我将选择标准定义为
import numpy as np
# An array of -1 values of shape(10,): [-1 -1 -1 -1 -1 -1 -1 -1 -1 -1]
arr_1 = np.zeros(10, dtype=int) - 1
# An array of 0-9 values of shape(10,): [0 1 2 3 4 5 6 7 8 9]
arr_2 = np.arange(10)
# Create an initial selection of values we want to change
# In this example: even indices: [ T F T F T F T F T F]
selection_a = np.arange(10) % 2 == 0
# Create a second selection based on selection_a: [F F F T T]
selection_b = arr_2[selection_a] > 5
基于这两个选择标准,我想将两个条件均成立的arr_2
的值分配给数组arr_1
。即等效于[F F F F F F T F T F]
。
arr_1[selection_a][selection_b] = arr_2[selection_a][selection_b]
如果我在分配前检查方程式的两边,它们会得出我期望的值:
print(arr_1[selection_a][selection_b]) # yields [-1 -1]
print(arr_2[selection_a][selection_b]) # yields [ 6, 8]
但是,分配本身并不分配值,即arr_1
保持不变。我的问题是,为什么会这样?
NB :我知道在大多数情况下(甚至可能在所有情况下),可以通过创建一个标准来规避这一问题,但是我想知道为什么使用2个单独的标准行不通。 / p>
如果不清楚,请告知我,我会尽力澄清。
我对此进行了进一步研究,问题似乎在等式的左侧,就像
arr_1[selection_a][selection_b] = 5
也不起作用。
答案 0 :(得分:3)
一次使用[...]
运算符会在数组中创建一个选择,您可以从中读取内容,也可以向其中写入内容。 [...]
的第二次使用将毫无问题地读取值。但是就写作而言,第二次访问将是根据您的情况创建的,与选择规则匹配的临时数组(即形状为(2,)
的临时数组,它是原始数据的副本)。
编辑:布尔索引是所谓的“高级索引”的一部分。将索引保持在简单的片上可以避免这些复制问题。
答案 1 :(得分:1)
添加到 Pierre de Buyl 解决方案中,如果要获得更改arr_1
数组所需的结果。您可以按以下方式使用np.where
:
arr_1[selection_a] = np.where(arr_2[selection_a]>5,arr_2[selection_a],arr_1[selection_a])
arr_1
哪个给
array([-1, -1, -1, -1, -1, -1, 6, -1, 8, -1])
答案 2 :(得分:1)
这与python中的=
解释为.__setitem__()
有关,后者可以从分配的变量中选择内存地址。但是,它不会递归执行此操作,因此
a[boolean_mask] = 0
有效,因为索引指向a
中的内存,
a[mask1][mask2] = 0
不会,因为索引指向a[mask1]
中的内存,该内存是副本。
答案 3 :(得分:0)
由于selection_a
和selection_b
的条件互不依赖,因此您可以创建一个合并的掩码
selection_c = (np.arange(10) % 2 == 0) & (arr_2 > 5)
并像使用它
arr_1[selection_c] = 5