Reputation: 395
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
Upvotes: 4
Views: 2657
Reputation: 33651
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]]
.
Upvotes: 11
Reputation: 9220
To replace multiple occurrence with single occurrence, append each item in a list if only the last appended item is not equal to the current one, and do the count.
def count_series(seq):
seq = iter(seq)
result = [next(seq, None)]
for item in seq:
if result[-1] != item:
result.append(item)
return result
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]
count_series(a).count(1)
5
Upvotes: 0
Reputation: 11
def num_events(list):
total = 0
in_event = 0
for current in list:
if current and not in_event:
total += 1
in_event = current
return total
This function iterates over the list from the left side and every time it encounters a 1 immediately after a 0, it increments the counter. In other words, it adds 1 to the total count at the start of each event.
Upvotes: 1
Reputation: 4250
Me being a simpleton ;-)
def get_number_of_events(event_list):
num_of_events = 0
for index, value in enumerate(event_list):
if 0 in (value, index):
continue
elif event_list[index-1] == 0:
num_of_events += 1
return num_of_events
Upvotes: 0
Reputation: 5927
Try this
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]
flag = 0
cnt = 0
for j in (a):
if( j == 1):
if(flag == 0):
cnt += 1
flag = 1
elif (j == 0):
flag = 0
print cnt
Upvotes: 1
Reputation: 2153
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 :)
Upvotes: 2