在NumPy中,
foo = np.array([[i+10*j for i in range(10)] for j in range(3)])
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]])
filter = np.nonzero(foo > 100)#nothing matches
foo[:,filter]
array([], shape=(3, 2, 0), dtype=int64)
foo[:,0:0]
array([], shape=(3, 0), dtype=int64)
filter2 = np.nonzero(np.sum(foo,axis=0) < 47)
foo[:,filter2]
array([[[ 0, 1, 2, 3, 4, 5]],
[[10, 11, 12, 13, 14, 15]],
[[20, 21, 22, 23, 24, 25]]])
foo[:,filter2].shape
(3, 1, 6)
我有一个'过滤器'条件,我想对所有匹配列的所有行执行操作,但如果filter是一个空数组,我的foo [:,filter]会以某种方式广播到3D数组中。另一个例子是filter2 - &gt;再次,foo [:,filter2]给我一个3D数组,当我期待foo的结果[:,(np.sum(foo,axis = 0)&lt; 47)]
有人能解释一下np.nonzero的正确使用情况与使用布尔找到正确的列/索引进行比较吗?
答案 0 :(得分:1)
首先,foo[filter] == foo[filter.nonzero()]
当filter
是布尔数组时。
要理解为什么你会得到意想不到的结果,你必须先了解一下python如何编制索引。要在python中进行多维索引,您可以使用[]
中的索引,用逗号分隔或使用元组。因此foo[1, 2, 3]
与foo[(1, 2, 3)]
相同。考虑到这一点,请查看执行foo[:, something]
时会发生什么。我相信你的例子是你试图获得foo[:, something[0], something[1]]
,而是你得到foo[(slice[None], (something[0], something[1]))]
。
这有点学术性,因为如果你只是使用filter
进行索引,你可能不需要使用非零,只需使用布尔数组作为索引,但如果需要,你可以做类似的东西:
foo[:, filter[0]]
# OR
index = (slice(None),) + filter.nonzero()
foo[index]