简体   繁体   中英

How to calculate numbers of “uninterrupted” repeats in an array in python?

I have a 0,1 numpy array like this:

 [0,0,0,1,1,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0]

I want to have a function that tells me number 1 is repeated 3,2,4 times in this array, respectively. Is there a simple numpy function for this?

This is one way to do it to find first the clusters and then get their frequency using Counter . The first part is inspired from this answer for 2d arrays. I added the second Counter part to get the desired answer.

If you find the linked original answer helpful, please visit it and upvote it.

from scipy.ndimage import measurements
from collections import Counter

arr = np.array([0,0,0,1,1,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0])

cluster, freq = measurements.label(arr)

print (list(Counter(cluster).values())[1:])
# [3, 2, 4]

Assume you only have 0s and 1s:

import numpy as np
a = np.array([0,0,0,1,1,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0])

# pad a with 0 at both sides for edge cases when a starts or ends with 1
d = np.diff(np.pad(a, pad_width=1, mode='constant'))
# subtract indices when value changes from 0 to 1 from indices where value changes from 1 to 0
np.flatnonzero(d == -1) - np.flatnonzero(d == 1)
# array([3, 2, 4])

A custom implementation?

def count_consecutives(predicate, iterable):
  tmp = []
  for e in iterable:
    if predicate(e): tmp.append(e)
    else:
      if len(tmp) > 0: yield(len(tmp)) # > 1 if you want at least two consecutive
      tmp = []
  if len(tmp) > 0: yield(len(tmp)) # > 1 if you want at least two consecutive

So you can:

array = [0,0,0,1,1,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0]
(count_consecutives(lambda x: x == 0, array)
#=> [3, 2, 4]

And also:

array = [0,0,0,1,2,3,0,0,3,2,1,0,0,1,11,10,10,0,0,100]
count_consecutives(lambda x: x > 1, array)
# => [2, 2, 3, 1]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM