2016-08-09 5 views
0

У меня есть произвольный массив только с двоичным с ценностно сказать:среднее число повторяющихся паттернов с Numpy

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

Что бы наиболее эффективным способом посчитать среднюю длину последовательностей 1s массива? Например. В этом примере это будет (1 + 8 + 2)/3.

+2

Сложность мудр: просто перебрать все значения и использовать некоторые активный/неактивный счетчик. Комбинируйте с однопроходным средним вычислением, и вы получите алгоритм O (n), который также является нижней границей (потому что вам нужно смотреть на все элементы хотя бы один раз). – sascha

+0

Я вижу. Хм, было интересно, есть ли у numpy внутренняя функция, которая могла бы каким-то образом подсчета шаблонов. Однако, спасибо! – Estilus

ответ

1

Я не уверен, что проще всего, но одна альтернатива

np.mean([len(list(v)) for k,v in itertools.groupby(a) if k]) 

3.6666666666666665 

Пояснение groupby группы смежных одинаковые значения вместе, мы фильтруем только те (if k), список понимание [...] создает список из длины подпоследовательностей единиц, т.е. [1,8,2], и mean вычисляет среднее значение.

+0

Этот выглядит очень хорошо. Спасибо! – Estilus

+0

Извините, но как вы думаете, вы могли бы объяснить, что происходит в этом коде? Раньше я никогда не использовал itertools. – Estilus

2

Для всех Numpy решения, вы можете использовать solution Alex Мартелли как так:

def runs_of_ones_array(bits): 
    # make sure all runs of ones are well-bounded 
    bounded = np.hstack(([0], bits, [0])) 
    # get 1 at run starts and -1 at run ends 
    difs = np.diff(bounded) 
    run_starts, = np.where(difs > 0) 
    run_ends, = np.where(difs < 0) 
    return run_ends - run_starts 

>>> a=np.array([1,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,1,0,]) 
>>> b=runs_of_ones_array(a) 
>>> float(sum(b))/len(b) 
3.66666666667