numpy.where(condition)的输出不是数组,而是数组的元组:为什么?

发布于 2021-01-29 15:08:56

我正在尝试该numpy.where(condition[, x, y])功能。
numpy文档中,我了解到,如果仅给出一个数组作为输入,它应该返回该数组非零的索引(即“
True”):

如果仅给出条件,则返回元组condition.nonzero(),其中condition为True的索引。

但是,如果尝试一下,它将返回一个包含两个元素的 元组 ,其中第一个是所需的索引列表,第二个是空元素:

>>> import numpy as np
>>> array = np.array([1,2,3,4,5,6,7,8,9])
>>> np.where(array>4)
(array([4, 5, 6, 7, 8]),) # notice the comma before the last parenthesis

所以问题是:为什么?这种行为的目的是什么?在什么情况下这很有用?确实,要获得所需的索引列表,我必须添加索引,如中所示np.where(array>4)[0],这似乎是“丑陋的”。


附录

我从一些答案中了解到,它实际上只是一个元素的元组。仍然我不明白为什么要这样输出。为了说明这是不理想的,请考虑以下错误(首先引起了我的问题):

>>> import numpy as np
>>> array = np.array([1,2,3,4,5,6,7,8,9])
>>> pippo = np.where(array>4)
>>> pippo + 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate tuple (not "int") to tuple

因此您需要做一些索引来访问实际的索引数组:

>>> pippo[0] + 1
array([5, 6, 7, 8, 9])
关注者
0
被浏览
87
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    在Python中(1)意味着1()可以自由添加到组号和表达式中以提高可读性(例如(1+3)*3v
    (1+3,)*3)。因此,要表示它使用的1元素元组(1,)(并要求您也使用它)。

    从而

    (array([4, 5, 6, 7, 8]),)
    

    是一个元素元组,该元素是一个数组。

    如果应用where到2d数组,结果将是2元素元组。

    结果where是可以将其直接插入分度槽,例如

    a[where(a>0)]
    a[a>0]
    

    应该返回相同的东西

    就像

    I,J = where(a>0)   # a is 2d
    a[I,J]
    a[(I,J)]
    

    或举个例子:

    In [278]: a=np.array([1,2,3,4,5,6,7,8,9])
    In [279]: np.where(a>4)
    Out[279]: (array([4, 5, 6, 7, 8], dtype=int32),)  # tuple
    
    In [280]: a[np.where(a>4)]
    Out[280]: array([5, 6, 7, 8, 9])
    
    In [281]: I=np.where(a>4)
    In [282]: I
    Out[282]: (array([4, 5, 6, 7, 8], dtype=int32),)
    In [283]: a[I]
    Out[283]: array([5, 6, 7, 8, 9])
    
    In [286]: i, = np.where(a>4)   # note the , on LHS
    In [287]: i
    Out[287]: array([4, 5, 6, 7, 8], dtype=int32)  # not tuple
    In [288]: a[i]
    Out[288]: array([5, 6, 7, 8, 9])
    In [289]: a[(i,)]
    Out[289]: array([5, 6, 7, 8, 9])
    

    ======================

    np.flatnonzero 展示了仅返回一个数组的正确方法,而不管输入数组的尺寸如何。

    In [299]: np.flatnonzero(a>4)
    Out[299]: array([4, 5, 6, 7, 8], dtype=int32)
    In [300]: np.flatnonzero(a>4)+10
    Out[300]: array([14, 15, 16, 17, 18], dtype=int32)
    

    它的文档说:

    这等效于a.ravel()。nonzero()[0]

    实际上,这实际上就是函数的功能。

    通过展平a消除了如何处理多个尺寸的问题。然后,它将响应从元组中删除,从而为您提供一个简单的数组。通过展平,它对于一维数组并没有特殊情况。

    ==========================

    @Divakar建议np.argwhere

    In [303]: np.argwhere(a>4)
    Out[303]: 
    array([[4],
           [5],
           [6],
           [7],
           [8]], dtype=int32)
    

    哪个 np.transpose(np.where(a>4))

    或者,如果您不喜欢列向量,则可以再次转置它

    In [307]: np.argwhere(a>4).T
    Out[307]: array([[4, 5, 6, 7, 8]], dtype=int32)
    

    除了现在是一个1xn数组。

    我们也可以包裹wherearray

    In [311]: np.array(np.where(a>4))
    Out[311]: array([[4, 5, 6, 7, 8]], dtype=int32)
    

    大量的以阵列出来的方式where元组([0]i,=transposearray,等等)。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看