I have the following array:
a = [0,0,0,1,1,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,1,1,0,1,1,1,0,0,0]
Each time I have a '1' or a series of them(consecutive), this is one event. I need to get, in Python, how many events my array has. So in this case we will have 5 events (that is 5 times 1 or sequences of it appears). I need to count such events in order to to get:
b = [5]
Thanks
You could use itertools.groupby
(it does exactly what you want - groups consecutive elements) and count all groups which starts with 1
:
In [1]: from itertools import groupby
In [2]: a = [0,0,0,1,1,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,1,1,0,1,1,1,0,0,0]
In [3]: len([k for k, _ in groupby(a) if k == 1])
Out[3]: 5
what if I wanted to add a condition that an event is given as long as there are is 2 or more '0's in between.
This could be done using groupby
and custom key
function:
from itertools import groupby
class GrouperFn:
def __init__(self):
self.prev = None
def __call__(self, n):
assert n is not None, 'n must not be None'
if self.prev is None:
self.prev = n
return n
if self.prev == 1:
self.prev = n
return 1
self.prev = n
return n
def count_events(events):
return len([k for k, _ in groupby(events, GrouperFn()) if k == 1])
def run_tests(tests):
for e, a in tests:
c = count_events(e)
assert c == a, 'failed for {}, expected {}, given {}'.format(e, a, c)
print('All tests passed')
def main():
run_tests([
([0, 1, 1, 1, 0], 1),
([], 0),
([1], 1),
([0], 0),
([0, 0, 0], 0),
([1, 1, 0, 1, 1], 1),
([0, 1, 1, 0, 1, 1, 0], 1),
([1, 0, 1, 1, 0, 1, 1, 0, 0, 1], 2),
([1, 1, 0, 0, 1, 1], 2),
([0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0], 4)
])
if __name__ == "__main__":
main()
The idea is pretty simple - when a 0
goes after a group of 1
's, it could be a part of the group and therefore should be included in that group. The next event either continues the group (if the event is 1
) or splits it (if the event is 0
)
Note, that presented approach will work only when you need to count a number of events, since it splits [1, 1, 0, 0]
as [[1, 1, 0], [0]]
.
Math way (be careful with an empty array):
a = [0,0,0,1,1,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,1,1,0,1,1,1,0,0,0]
events = (a[0] + a[-1] + sum(a[i] != a[i-1] for i in range(1, len(a)))) / 2
print events
I like to think this is efficient :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With