【问题标题】:numpy get index where value is truenumpy 获取值为真的索引
【发布时间】:2013-04-12 06:04:39
【问题描述】:
>>> ex=np.arange(30)
>>> e=np.reshape(ex,[3,10])
>>> e
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]])
>>> e>15
array([[False, False, False, False, False, False, False, False, False,
        False],
       [False, False, False, False, False, False,  True,  True,  True,
         True],
       [ True,  True,  True,  True,  True,  True,  True,  True,  True,
         True]], dtype=bool)

我需要在 e 中找到值为 true 的行或值大于 15 的行。我可以使用 for 循环进行迭代,但是,我想知道 numpy 是否有办法做到这一点有效吗?

【问题讨论】:

    标签: python numpy matrix


    【解决方案1】:

    获取至少一项大于 15 的行号:

    >>> np.where(np.any(e>15, axis=1))
    (array([1, 2], dtype=int64),)
    

    【讨论】:

    • np.where 文档指出:“当仅提供条件时,此函数是 np.asarray(condition).nonzero() 的简写。应首选直接使用nonzero 因为它对子类行为正确。"
    【解决方案2】:

    您可以使用nonzero 函数。它返回给定输入的非零索引。

    简单的方法

    >>> (e > 15).nonzero()
    
    (array([1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]), array([6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
    

    要更清晰地查看索引,请使用transpose 方法:

    >>> numpy.transpose((e>15).nonzero())
    
    [[1 6]
     [1 7]
     [1 8]
     [1 9]
     [2 0]
     ...
    

    不错的方式

    >>> numpy.nonzero(e > 15)
    
    (array([1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]), array([6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
    

    或干净的方式:

    >>> numpy.transpose(numpy.nonzero(e > 15))
    
    [[1 6]
     [1 7]
     [1 8]
     [1 9]
     [2 0]
     ...
    

    【讨论】:

    • np.nonzero()np.where() 使用的 under the hood
    • np.transpose(np.where(board==0)) 对我有用
    • 感谢您提到需要转置数组。我花了半个小时质疑我为什么返回不存在的索引。
    【解决方案3】:

    一种简单而干净的方法:使用np.argwhere按元素分组索引,而不是像np.nonzero(a)中的维度(即np.argwhere为每个非零元素返回一行)。

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

    np.argwhere(a)np.transpose(np.nonzero(a)) 几乎相同,但它会生成正确形状的 0 维数组的结果。

    注意:您不能使用a(np.argwhere(a>4)) 来获取a 中的对应值。推荐的方法是使用a[(a>4).astype(bool)]a[(a>4) != 0] 而不是a[np.nonzero(a>4)],因为它们可以正确处理0-d 数组。有关详细信息,请参阅documentation。从下面的例子可以看出,a[(a>4).astype(bool)]a[(a>4) != 0]可以简化为a[a>4]

    另一个例子:

    >>> a = np.array([5,-15,-8,-5,10])
    >>> a
    array([  5, -15,  -8,  -5,  10])
    >>> a > 4
    array([ True, False, False, False,  True])
    >>> a[a > 4]
    array([ 5, 10])
    >>> a = np.add.outer(a,a)
    >>> a
    array([[ 10, -10,  -3,   0,  15],
           [-10, -30, -23, -20,  -5],
           [ -3, -23, -16, -13,   2],
           [  0, -20, -13, -10,   5],
           [ 15,  -5,   2,   5,  20]])
    >>> a = np.argwhere(a>4)
    >>> a
    array([[0, 0],
           [0, 4],
           [3, 4],
           [4, 0],
           [4, 3],
           [4, 4]])
    >>> for i,j in a: print(i,j)
    ... 
    0 0
    0 4
    3 4
    4 0
    4 3
    4 4
    >>>
    

    【讨论】:

      【解决方案4】:

      当您只需要行 idx 时,我更喜欢 np.flatnonzero(arr) 而不是 nonzero() 选项。 arr.nonzero() 有效,但它返回一个元组而不是一个数组。 flatnonzero() 等价于np.nonzero(np.ravel(arr))[0]

      如 cmets 中所述,NumPy 文档不鼓励np.where()

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-16
        • 2018-02-16
        • 1970-01-01
        • 1970-01-01
        • 2021-08-13
        • 1970-01-01
        • 2018-10-22
        • 1970-01-01
        相关资源
        最近更新 更多