为什么np.argwhere的结果形状与它的输入不匹配?

时间:2018-03-21 22:07:18

标签: python arrays numpy

假设我传递了1D数组:

>>> np.arange(0,20)
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19])
>>> np.arange(0,20).shape
(20,)

进入argwhere:

>>> np.argwhere(np.arange(0,20)<10)
array([[0],
       [1],
       [2],
       [3],
       [4],
       [5],
       [6],
       [7],
       [8],
       [9]])
>>> np.argwhere(np.arange(0,20)<10).shape
(10, 1)

为什么结果会变成2D数组?这有什么好处?

3 个答案:

答案 0 :(得分:3)

argwhere返回where条件为True的坐标。通常,坐标是元组,因此输出应为2D。

>>> np.argwhere(np.arange(0,20).reshape(2,2,5)<10)
array([[0, 0, 0],
       [0, 0, 1],
       [0, 0, 2],
       [0, 0, 3],
       [0, 0, 4],
       [0, 1, 0],
       [0, 1, 1],
       [0, 1, 2],
       [0, 1, 3],
       [0, 1, 4]])

为了保持一致性,这也适用于1D输入的情况。

答案 1 :(得分:0)

numpy.argwhere找到满足条件的元素的索引。碰巧你的一些元素本身就是输出元素(索引与值相同)。

特别是,在您的示例中,输入是一维的,输出是一维(索引)乘二(第二个是迭代值)。

我希望这很清楚,如果没有,请参考numpy文档中提供的二维输入数组示例:

>>> x = np.arange(6).reshape(2,3)
>>> x
array([[0, 1, 2],
       [3, 4, 5]])
>>> np.argwhere(x>1)
array([[0, 2],
       [1, 0],
       [1, 1],
       [1, 2]])

答案 2 :(得分:0)

argwhere只是where的转置(实际为np.nonzero):

In [17]: np.where(np.arange(0,20)<10)
Out[17]: (array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),)
In [18]: np.transpose(_)
Out[18]: 
array([[0],
       [1],
       [2],
       [3],
       [4],
       [5],
       [6],
       [7],
       [8],
       [9]])

where生成一个数组元组,每个维度一个数组(这里是1个元素元组)。 transpose将该元组转换为数组(例如(1,10)形状),然后将其转置。所以它的列数是输入条件的ndim,行数是finds的数量。

argwhere可用于可视化查找,但在程序中不如where本身有用。 where元组可用于直接索引条件数组。 argwhere数组通常以迭代方式使用。例如:

In [19]: x = np.arange(10).reshape(2,5)
In [20]: x %2
Out[20]: 
array([[0, 1, 0, 1, 0],
       [1, 0, 1, 0, 1]])
In [21]: np.where(x%2)
Out[21]: (array([0, 0, 1, 1, 1]), array([1, 3, 0, 2, 4]))
In [22]: np.argwhere(x%2)
Out[22]: 
array([[0, 1],
       [0, 3],
       [1, 0],
       [1, 2],
       [1, 4]])
In [23]: x[np.where(x%2)]
Out[23]: array([1, 3, 5, 7, 9])
In [24]: for i in np.argwhere(x%2):
    ...:     print(x[tuple(i)])
    ...:     
1
3
5
7
9
In [25]: [x[tuple(i)] for i in np.argwhere(x%2)]
Out[25]: [1, 3, 5, 7, 9]