Обнаружение периодических повторений в потоке данных


Допустим, у меня есть массив нулей:

a = numpy.zeros(1000)

Затем я ввожу некоторые повторяющиеся "события":

a[range(0, 1000, 30)] = 1

Вопрос в том, как я могу обнаружить "сигнал" там? Поскольку это далеко не идеальный сигнал, если я делаю "обычный" FFT, я не получаю четкого указания, где находится мой "истинный" сигнал:

f = abs(numpy.fft.rfft(a))

Существует ли метод для обнаружения этих повторений с некоторой степенью уверенности? Особенно, если у меня есть несколько из них, смешанных, например здесь:

a[range(0, 1000, 30)] = 1
a[range(0, 1000, 110)] = 1
a[range(0, 1000, 48)] = 1

Я хотел бы получить три "Спайка" на результирующих данных...

2 2

2 ответа:

В качестве аналитического метода используются acf / pacf/ccf для идентификации периодичности в зависящих от времени сигналах, следовательно, коррелограмма, графическое отображение acf или pacf, отображает самоподобие в сигнале как функцию различных лагов. (Например, если вы видите значения на оси y с запаздыванием 12, и если ваша дата находится в месяцах, это свидетельствует о годовой периодичности.)

Чтобы вычислить и построить график "сходства" по сравнению с лагом, если вы не хотите свернуть свой собственный, я не знаю родной вариант Numpy/Scipy; я также не смог найти его в scikit 'time series' (одна из библиотек в Scipy 'Scikits', доменные модули, не включенные в стандартный дистрибутив Scipy), но это стоит проверить еще раз. Другой вариант-установить привязки Python к R (RPy2, доступные на SourceForge), которые позволят вам получить доступ к соответствующим функциям R, включая ' acf', которые будут вычислять и строить коррелограмму, просто проходя в вашем временном ряду и вызывая функция.

С другой стороны, если вы хотите идентифицировать непрерывные (непрерывные) потоки заданного типа в вашем сигнале, то" кодирование длины пробега ", вероятно, то, что вы хотите:

import numpy as NP
signal = NP.array([3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,7,7,7,7,7,4,4,1,1,1,1,1,1,1])
px, = NP.where(NP.ediff1d(signal) != 0)
px = NP.r_[(0, px+1, [len(signal)])]
# collect the run-lengths for each unique item in the signal
rx = [ (m, n, signal[m]) for (m, n) in zip(px[:-1], px[1:]) ]

# returns [(0, 9, 3), (9, 19, 0), (19, 24, 7), (24, 26, 4), (26, 33, 1)]
# so w/r/t first 3-tuple: '3' occurs continuously in the half-open interval 0 and 9, and so forth

Рассматривали ли вы возможность использования автокорреляции ?