numpy:如何在numpy数组的每一列中查找第一个非零值?

发布于 2021-01-29 19:31:54

假设我有以下形式的numpy数组:

arr=numpy.array([[1,1,0],[1,1,0],[0,0,1],[0,0,0]])

我想找到第一个索引(对于每一列)的索引,其中值非零。

因此,在这种情况下,我希望返回以下内容:

[0,0,2]

我该怎么办?

关注者
0
被浏览
183
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    首次出现的指标

    使用np.argmax沿轴(零轴这里列)非零的面具拿到第一的指标matches(真实值)

    (arr!=0).argmax(axis=0)
    

    扩展到涵盖通用轴说明符,并且在沿着该轴找不到元素的非零的情况下,我们将有一个类似的实现-

    def first_nonzero(arr, axis, invalid_val=-1):
        mask = arr!=0
        return np.where(mask.any(axis=axis), mask.argmax(axis=axis), invalid_val)
    

    请注意,由于argmax()所有False值都会返回0,因此如果invalid_val需要的话0,我们将直接使用生成最终输出mask.argmax(axis=axis)

    样品运行-

    In [296]: arr    # Different from given sample for variety
    Out[296]: 
    array([[1, 0, 0],
           [1, 1, 0],
           [0, 1, 0],
           [0, 0, 0]])
    
    In [297]: first_nonzero(arr, axis=0, invalid_val=-1)
    Out[297]: array([ 0,  1, -1])
    
    In [298]: first_nonzero(arr, axis=1, invalid_val=-1)
    Out[298]: array([ 0,  0,  1, -1])
    

    扩展到涵盖所有比较操作

    为了找到第一zeros,简单地使用arr==0作为mask在功能使用。对于等于某个特定值的第一个valarr == valcomparisons此处对所有可能的情况使用等等。


    最近一次出现的指标

    要找到符合特定比较标准的最后一个,我们需要沿该轴翻转,并使用相同的用法argmax,然后通过偏离轴长来补偿该翻转,如下所示-

    def last_nonzero(arr, axis, invalid_val=-1):
        mask = arr!=0
        val = arr.shape[axis] - np.flip(mask, axis=axis).argmax(axis=axis) - 1
        return np.where(mask.any(axis=axis), val, invalid_val)
    

    样品运行-

    In [320]: arr
    Out[320]: 
    array([[1, 0, 0],
           [1, 1, 0],
           [0, 1, 0],
           [0, 0, 0]])
    
    In [321]: last_nonzero(arr, axis=0, invalid_val=-1)
    Out[321]: array([ 1,  2, -1])
    
    In [322]: last_nonzero(arr, axis=1, invalid_val=-1)
    Out[322]: array([ 0,  1,  1, -1])
    

    同样,comparisons这里所有可能的情况都通过使用相应的比较器进行获取mask,然后在列出的函数中使用来覆盖。



知识点
面圈网VIP题库

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

去下载看看