Как получить пиковые значения из преобразования Фурье? - PullRequest
0 голосов
/ 28 января 2020

Я подозреваю, что что-то мне не хватает в моем понимании преобразования Фурье, поэтому я ищу некоторую поправку (если это так). Как мне собрать пиковую информацию с первого графика ниже?

Набор данных - это почасовые данные для 911 вызовов за последние 17 лет (для определенного города).

Я удалил тренд по моим данным, и сейчас убираю сезонность. Когда я запускаю преобразование Фурье, я получаю следующий график: enter image description here

Я считаю, что в наборе данных есть некоторая сезонность (глядя на еженедельные данные, у меня есть этот шаблон): enter image description here

Как выбрать значения пиков на первом графике? Предположительно для всех «пиков», скажем, 5000 на первом графике, я могу игнорировать включение этой сезонности в мою окончательную модель, но только с потерей точности, верно?

Вот немного код, с которым я сейчас работаю:

from scipy import fftpack
fft = fftpack.fft(calls_grouped_hour.detrended_residuals - calls_grouped_hour.detrended_residuals.mean())
plt.plot(1./(17*365)*np.arange(len(fft)), np.abs(fft))
plt.xlim([-.1, 23/2]);

РЕДАКТИРОВАТЬ: После первоначального ответа Марка Снайдера у меня есть следующий график: enter image description here

Добавление кода попытки получить пиковые значения из fft:

Нужно ли сначала преобразовывать значения, используя ifft?

fft_x_y = np.stack((fft.real, fft.imag), -1)
peaks = []
for x, y in np.abs(fft_x_y):
    if (y >= 0): 
        spipeakskes.append(x)

peaks = np.unique(peaks)
print('Length: ', len(peaks))
print('Peak values: ', '\n', np.sort(peaks))

1 Ответ

1 голос
/ 28 января 2020
threshold = 5000
fft[np.abs(fft)<threshold] = 0

Это даст вам fft, который игнорирует все, кроме пиков. И нет, я бы не подумал, что «шум» представляет собой фактическую сезонность. Пик в fft[0] также не отражает сезонность - он кратен среднему значению данных, поэтому, если вы планируете вычитать ifft из пиков, я бы тоже не включил fft[0], если вы не хотите данные для центрирования.

Если вы хотите просто пиковые значения, а не полные fft, которые вы можете инвертировать, вы можете просто сделать это:

peaks = [np.abs(value) for value in fft if np.abs(value)>threshold]

...