简体   繁体   English

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

[英]How to find first non-zero value in every column of a numpy array?

Suppose I have a numpy array of the form:假设我有一个形式为 numpy 的数组:

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

I want to find the indices of the first index (for every column) where the value is non-zero.我想找到值不为零的第一个索引(对于每一列)的索引。

So in this instance, I would like the following to be returned:因此,在这种情况下,我希望返回以下内容:

[0,0,2]

How do I go about this?我该怎么做?

Indices of first occurrences 首次出现的指标

Use np.argmax along that axis (zeroth axis for columns here) on the mask of non-zeros to get the indices of first matches (True values) - np.argmax沿该轴(此处为列的零轴)使用np.argmax可获得首个matches的索引(真值)-

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

Extending to cover generic axis specifier and for cases where no non-zeros are found along that axis for an element, we would have an implementation like so - 扩展到涵盖通用轴说明符,并且在沿着该轴找不到元素的非零的情况下,我们将有一个类似的实现-

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

Note that since argmax() on all False values returns 0 , so if the invalid_val needed is 0 , we would have the final output directly with mask.argmax(axis=axis) . 注意,由于所有False值上的argmax()返回0 ,因此,如果所需的invalid_val0 ,我们将直接使用mask.argmax(axis=axis)获得最终输出。

Sample runs - 样品运行-

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])

Extending to cover all comparison operations 扩展到涵盖所有比较操作

To find the first zeros , simply use arr==0 as mask for use in the function. 要找到第一个zeros ,只需将arr==0用作函数中的mask For first ones equal to a certain value val , use arr == val and so on for all cases of comparisons possible here. 对于等于某个特定值val第一个值,请使用arr == val ,依此类推,对于此处所有可能的comparisons情况。


Indices of last occurrences 最近一次出现的指标

To find the last ones matching a certain comparison criteria, we need to flip along that axis and use the same idea of using argmax and then compensate for the flipping by offsetting from the axis length, as shown below - 要找到符合特定比较条件的最后一个,我们需要沿该轴翻转并使用使用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)

Sample runs - 样品运行-

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])

Again, all cases of comparisons possible here are covered by using the corresponding comparator to get mask and then using within the listed function. 同样,使用相应的比较器获取mask ,然后在列出的函数中使用,可以覆盖所有可能的comparisons情况。

Here is an alternative using numpy.argwhere which returns the index of the non zero elements of an array:这是使用numpy.argwhere的替代方法,它返回数组的非零元素的索引:

array = np.array([0,0,0,1,2,3,0,0])

nonzero_indx = np.argwhere(array).squeeze()
start, end = (nonzero_indx[0], nonzero_indx[-1])
array[start:end]

gives:给出:

array([1, 2])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM