hpnk85
hpnk85

Reputation: 395

count number of events in an array python

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

Answers (7)

awesoon
awesoon

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

Nizam Mohamed
Nizam Mohamed

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

rwoll
rwoll

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

thiruvenkadam
thiruvenkadam

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

Aguy
Aguy

Reputation: 8059

One more:

sum([(a[i] - a[i-1])>0 for i in range(1, len(a))])

Upvotes: 1

mkHun
mkHun

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

lcastillov
lcastillov

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

Related Questions