1

I have a numpy 1d arrays with boolean values, that looks like

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

This arrays have different length. As you can see, there are parts, where True values located next to each other, so we have groups of Trues and groups of Falses. I want to count the number of True groups. For our case, we have

N = 2

I tried to do some loops with conditions, but it got really messy and confusing.

4 Answers 4

3

You can use np.diff to determine changes between groups. By attaching False to the start and the end of this difference calculation we make sure that True groups at the start and end are properly counted.

import numpy as np

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

true_groups = np.sum(np.diff(array_in, prepend=False, append=False))//2

#print(true_groups)
>>>4
Sign up to request clarification or add additional context in comments.

2 Comments

Your result is 4, not 2
Because this input array is different.
1

If you don't want to write loops and conditions, you could take a shortcut by looking at this like a connected components problem.

import numpy as np
from skimage import measure

array_in = np.array([False, True, True, True, False, False, True, True, False])
N = max(measure.label(array_in))

When an array is passed into the measure.label() function, it treats the 0 values in that array as the "background". Then it looks at all the non-zero values, finds connected regions, and numbers them.

For example, the label output on the above array will be [0, 1, 1, 1, 0, 0, 2, 2, 0]. Naturally, then doing a simple max on the output gives you the largest group number (here it's 2) -- which is also the same as the number of True groups.

3 Comments

Interesting view on the problem. How does it work?
When an array is passed into the measure.label() function, it treats the 0 values in that array as the "background". Then it looks at all the non-zero values, finds connected regions, and numbers them. For example, the label output on the above array will be [0, 1, 1, 1, 0, 0, 2, 2, 0]. Naturally, then doing a simple max on the output gives you the largest group number (here it's 2) -- which is also the same as the number of True groups.
Care to add this to your answer?
0

A straightforward way of finding the number of groups of True is by counting the number of False, True sequences in the array. With a list comprehension, that will look like:

sum([1 for i in range(1, len(x)) if x[i] and not x[i-1]])

Alternatively you can convert the initial array into a string of '0's and '1's and count the number of '01' occurences:

''.join([str(int(k)) for k in x]).count('01')

Comments

0

In native numpy, a vectorised solution can be done by checking how many times F changes to T sequentially.

For example,

np.bitwise_and(array_in[1:], ~array_in[:-1]).sum() + array_in[0]

I am computing a bitwise and of every element of the array with it's previous element after negating the previous element. However, in doing so, the first element is ignored, so I am adding that in manually.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.