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

时间:2017-11-13 16:44:30

标签: python numpy

假设我有一个numpy数组:

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

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

所以在这个例子中,我希望返回以下内容:

[0,0,2]

我该怎么做?

1 个答案:

答案 0 :(得分:34)

首次出现的指数

在非零的掩码上沿该轴使用np.argmax(此处为列的第0轴)以获取第一个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_val0,我们将直接使用最终输出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即可在函数中使用。对于等于特定值val的第一个,请使用arr == val,依此类推{000}所有comparisons的情况。

最后一次出现的指数

要查找与某个比较条件匹配的最后一个,我们需要沿着该轴翻转并使用相同的使用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])

同样,通过使用相应的比较器得到mask然后在列出的函数中使用,可以涵盖comparisons可能的所有情况。