【问题标题】:Getting indices of both zero and nonzero elements in array获取数组中零元素和非零元素的索引
【发布时间】:2012-11-28 06:09:56
【问题描述】:

我需要找到数组的零元素和非零元素的索引。

换句话说,我想从numpy.nonzero() 中找到互补索引。

我知道的方法如下:

indices_zero = numpy.nonzero(array == 0)
indices_nonzero = numpy.nonzero(array != 0)

然而,这意味着搜索数组两次,这对于大型数组效率不高。有没有使用 numpy 的有效方法来做到这一点?

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    假设您已经有了numpy.arange(len(array)) 的使用范围,只需获取并存储逻辑索引:

    bindices_zero = (array == 0)
    

    那么当你真正需要整数索引时,你可以这样做

    indices_zero = numpy.arange(len(array))[bindices_zero]
    

    indices_nonzero = numpy.arange(len(array))[~bindices_zero]
    

    【讨论】:

    • 对于我所需要的,@bmu 提供了最佳答案。不过,你的回答正好回答了我的问题,所以我会勾选这个。
    【解决方案2】:

    您可以使用布尔索引:

    In [82]: a = np.random.randint(-5, 5, 100)
    
    In [83]: a
    Out[83]: 
    array([-2, -1,  4, -3,  1, -2,  2, -1,  2, -1, -3,  3, -3, -4,  1,  2,  1,
            3,  3,  0,  1, -3, -4,  3, -5, -1,  3,  2,  3,  0, -5,  4,  3, -5,
           -3,  1, -1,  0, -4,  0,  1, -5, -5, -1,  3, -2, -5, -5,  1,  0, -1,
            1,  1, -1, -2, -2,  1,  1, -4, -4,  1, -3, -3, -5,  3,  0, -5, -2,
           -2,  4,  1, -4, -5, -1,  3, -3,  2,  4, -4,  4,  2, -2, -4,  3,  4,
           -2, -4,  2, -4, -1,  0, -3, -1,  2,  3,  1,  1,  2,  1,  4])
    
    In [84]: mask = a != 0
    
    In [85]: a[mask]
    Out[85]: 
    array([-2, -1,  4, -3,  1, -2,  2, -1,  2, -1, -3,  3, -3, -4,  1,  2,  1,
            3,  3,  1, -3, -4,  3, -5, -1,  3,  2,  3, -5,  4,  3, -5, -3,  1,
           -1, -4,  1, -5, -5, -1,  3, -2, -5, -5,  1, -1,  1,  1, -1, -2, -2,
            1,  1, -4, -4,  1, -3, -3, -5,  3, -5, -2, -2,  4,  1, -4, -5, -1,
            3, -3,  2,  4, -4,  4,  2, -2, -4,  3,  4, -2, -4,  2, -4, -1, -3,
           -1,  2,  3,  1,  1,  2,  1,  4])
    
    In [86]: a[-mask]
    Out[86]: array([0, 0, 0, 0, 0, 0, 0])
    

    【讨论】:

    • 是的,这就是我需要的。我忘记了我能做到这一点。谢谢。
    【解决方案3】:

    我不确定用于完成此任务的内置 numpy 方法,但我相信您可以使用老式的 for 循环。比如:

    indices_zero = []
    indices_nonzero = []
    
    for index in xrange(len(array)):
        if array[index] == 0:
            indicies_zero.append(index)
        else:
            indicies_nonzero.append(index)
    

    这样的事情应该完成你想要的,只循环一次。

    【讨论】:

    • 是的,这会起作用,但如果用 python 编写,它可能会比调用两次 numpy 例程慢。我可以在 cython 中执行此操作以获得性能,但我希望有一个更简单的解决方案。
    • 我没有使用 numpy,但只是作为一个想法......有 numpy 矢量化操作吗?如果是这样,您可以获得逻辑值向量为零,将其反转(快速)并获取具有非零值的逻辑值向量。将此值应用于矩阵形式的数组将使您两个 vectros 都比简单的迭代更快。
    猜你喜欢
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    • 2011-05-05
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多