Home > Software engineering >  Finding the first and last occurrences in a numpy array
Finding the first and last occurrences in a numpy array

Time:12-22

I have a (large) numpy array of boolean values, where the True indicate the zero-crossing condition of another previously processed signal. In my case, I am only interested in the indexes of the first and last True values in the array and therefore I'd rather not use np.where or np.argwhere in order to avoid going through the entire array unnecessarily.

I'd prefer not to convert my array into a list and use the index() method. Or should I?

So far, the best solution I have come up with is the following:

# Alias for compactness
enum = enumerate

# Example array, desired output = (3, -5))
a = np.array([False, False, False, True, ..., True, False, False, False, False])


out = next(idx for idx in zip((i for i, x in enum(a) if x), (-i-1 for i, x in enum(a[::-1]) if x)))

print(out)
# (3, -5)

But I still find it a bit bulky and wonder wheter Numpy alreadys implement such functionality with another syntax. Does it?

CodePudding user response:

Use numpy's nonzero function, which returns the indices of all non-zero elements in the input array:

a = np.array([False, False, False, True, ..., True, False, False])

# Find the indices of the non-zero elements
indices = np.nonzero(a)

# The first and last indices will be the first and last True values
first = indices[0][0]
last = indices[0][-1]

CodePudding user response:

How about this?

import numpy as np

a = np.array([False, False, False, True, False, True, False, False, False, False])

out = (np.argmax(a), a.size - np.argmax(a[::-1]) - 1)

np.argmax() stops at the first True value, so this might solve your problem of not wanting to iterate over the whole array? Inspired by this answer.

  • Related