1

Good evening,

Is there a efficient way of getting all beginning and ending indexes of True values in a boolean array? Let's say I have this array:

x = np.array([nan, 11, 13, nan, nan, nan, 9, 3, nan, 3, 4, nan])

I use np.isnan(x) so I get:

[True, False, F, T, T, T, F, F, T, F, F, T]

I would like to have at the end an array or list with only indexes of NaN -> i.e one index if single, or beginning index and ending index if consecutive NaN values: [0, [3, 5], 8, 11]

Do I have to loop on the array myself and write a function or is there a numpy and efficient way of doing it?

I have already something running but as I have to deal with hundred of thousands of values per array and multiples array also, it takes time.

0

2 Answers 2

4

You can use groupby from itertools module:

lst = []
for mask, grp in groupby(zip(np.arange(len(x)), np.isnan(x)), key=lambda x: x[1]):
    if mask == True:  # only for NaN
        idx = [idx for idx, _ in grp]
        lst.append([idx[0], idx[-1]] if len(idx) > 1 else idx[0])

Output:

>>> lst
[0, [3, 5], 8, 11]
Sign up to request clarification or add additional context in comments.

3 Comments

Woaw, 100k, congratz!!! :)
Now it is ;) congrats
Today I learned it rounds up... still a phenomenal achievement ;)
2

You can use boolean operations shifting the np.isnan output on the left/right:

# if the value a NaN?
m = np.isnan(x)
# is the preceding value not a NaN?
m2 = np.r_[False, ~m[:-1]]
# is the following value not a NaN?
m3 = np.r_[~m[1:], False]

out = np.where((m&m2)|(m&m3))[0]

Output:

array([ 0,  3,  5,  8, 11])

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.