当我运行此代码时:
import numpy as np
a = np.array([1, 2, 3, 4, 5, 6])
print(np.where(a > 2))
获得a > 2
的{{1}}索引数组是很自然的,但我们得到:
[2, 3, 4, 5]
即。一个空的第二个成员的元组。
然后,要获得(array([2, 3, 4, 5], dtype=int64),)
的“自然”答案,我们必须这样做:
numpy.where
这个元组有什么意义?在哪种情况下有用?
注意:我在这里只是谈论用例np.where(a > 2)[0]
而不是numpy.where(cond)
也存在(参见文档)。
答案 0 :(得分:5)
numpy.where
返回一个元组,因为元组的每个元素都引用一个维度。
在2个维度中考虑这个例子:
a = np.array([[1, 2, 3, 4, 5, 6],
[-2, 1, 2, 3, 4, 5]])
print(np.where(a > 2))
(array([0, 0, 0, 0, 1, 1, 1], dtype=int64),
array([2, 3, 4, 5, 3, 4, 5], dtype=int64))
如您所见,元组的第一个元素是指相关元素的第一维;第二个元素是指第二个维度。
这是numpy
经常使用的约定。当你要求数组的形状时,你也会看到它,即一维数组的形状将返回一个带有1个元素的元组:
a = np.array([[1, 2, 3, 4, 5, 6],
[-2, 1, 2, 3, 4, 5]])
print(a.shape, a.ndim) # (2, 6) 2
b = np.array([1, 2, 3, 4, 5, 6])
print(b.shape, b.ndim) # (6,) 1
答案 1 :(得分:2)
为了保持一致性:元组的长度与输入数组的维数相匹配。
>>> np.where(np.ones((1)) > 0)
(array([0]),)
>>> np.where(np.ones((1,1)) > 0)
(array([0]), array([0]))
>>> np.where(np.ones((1,1,1)) > 0)
(array([0]), array([0]), array([0]))
使1-d情况返回数组而不是元组将导致不均匀的返回类型。如果调用者代码处理任意形状的输入数据,则程序员必须对返回值中的1-d输入进行特殊情况处理。
答案 2 :(得分:1)
来自np.where
如果只给出条件,则返回元组condition.nonzero(),条件为True的索引
所以我们查看'np.nonzero'
的文档返回一个数组元组,每个维度一个,包含该维度中非零元素的索引。始终测试a中的值并以行主要C样式顺序返回。相应的非零值可以通过以下方式获得:
那么np.where/np.nonzero
如何能够有用返回一个数组元组?我认为这与indexing multi-dimensional arrays有关。
来自documentation的例子,如果我们有
y = np.arange(35).reshape(5,7)
我们可以做到
y[np.array([0,2,4]), np.array([0,1,2])]
选择y[0, 0]
,y[2, 1]
,y[4, 2]
。
在这种情况下,如果索引数组具有匹配的形状,并且索引的数组的每个维度都有一个索引数组,则结果数组具有与索引数组相同的形状,并且值对应于索引为索引数组中的每个位置设置。在此示例中,两个索引数组的第一个索引值均为0,因此结果数组的第一个值为y [0,0]。下一个值是y [2,1],最后一个是y [4,2]。
希望索引多维数组可以证明np.nonzero/np.where
返回一个数组元组,以便以后可以用它来选择元素。