Обнаружение периодических повторений в потоке данных
Допустим, у меня есть массив нулей:
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 ответа:
В качестве аналитического метода используются 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
Рассматривали ли вы возможность использования автокорреляции ?