Я анализирую то, что по сути является формой волны дыхания, построенной в 3 различных формах (данные получены из МРТ, поэтому использовалось несколько периодов эхо-сигнала; см. здесь, если вам нужна краткая информация). Вот пара сегментов двух построенных сигналов для некоторого контекста:
Для каждой формы волны я пытаюсь выполнить ДПФ, чтобы обнаружить доминирующую частоту или частоты дыхания.
Моя проблема в том, что когда я рисую ДПФ, которые я выполняю, я получаю одну из двух вещей, в зависимости от библиотеки БПФ, которую я использую. Кроме того, ни один из них не является репрезентативным для того, что я ожидаю. Я понимаю, что данные не всегда выглядят так, как мы хотим, но в моих данных явно присутствуют сигналы, поэтому я ожидаю дискретного Преобразование Фурье для получения частотного пика где-то в разумных пределах. Для справки здесь, я бы ожидал от 80 до 130 Гц.
Мои данные хранятся в фрейме данных pandas
, причем данные каждого времени эха находятся в отдельной серии. Я применяю выбранную функцию БПФ (см. код ниже) и получаю разные результаты для каждого из них.
Наука (fftpack
)
import pandas as pd
import scipy.fftpack
# temporary copy to maintain data structure
lead_pts_fft_df = lead_pts_df.copy()
# apply a discrete fast Fourier transform to each data series in the data frame
lead_pts_fft_df.magnitude = lead_pts_df.magnitude.apply(scipy.fftpack.fft)
lead_pts_fft_df
Числовой:
import pandas as pd
import numpy as np
# temporary copy to maintain data structure
lead_pts_fft_df = lead_pts_df.copy()
# apply a discrete fast Fourier transform to each data series in the data frame
lead_pts_fft_df.magnitude = lead_pts_df.magnitude.apply(np.fft.fft)
lead_pts_fft_df
Остальная часть соответствующего кода:
ECHO_TIMES = [0.080, 0.200, 0.400] # milliseconds
f_s = 1 / (0.006) # 0.006 = time between samples
freq = np.linspace(0, 29556, 29556) * (f_s / 29556) # (29556 = length of data)
# generate subplots
fig, axes = plt.subplots(3, 1, figsize=(18, 16))
for idx in range(len(ECHO_TIMES)):
axes[idx].plot(freq, lead_pts_fft_df.magnitude[idx].real, # real part
freq, lead_pts_fft_df.magnitude[idx].imag, # imaginary part
axes[idx].legend() # apply legend to each set of axes
# show the plot
plt.show()
Пост-ТПФ (SciPy fftpack
):
Пост-ДПФ (NumPy)
Вот ссылка на набор данных (в Dropbox), который использовался для создания эти графики, и здесь есть ссылка на Блокнот Юпитер.
РЕДАКТИРОВАТЬ:
Я воспользовался опубликованным советом и взял величину (абсолютное значение) данных, а также построил график с логарифмической осью Y. Новые результаты опубликованы ниже. Похоже, у меня есть некоторый заворот в моем сигнале. Я использую неправильную шкалу частот? Обновленный код и графики приведены ниже.
# generate subplots
fig, axes = plt.subplots(3, 1, figsize=(18, 16))
for idx in range(len(ECHO_TIMES)):
axes[idx].plot(freq[1::], np.log(np.abs(lead_pts_fft_df.magnitude[idx][1::])),
label=lead_pts_df.index[idx], # apply labels
color=plot_colors[idx]) # colors
axes[idx].legend() # apply legend to each set of axes
# show the plot
plt.show()
log(abs(fft))
? - person Cris Luengo   schedule 26.07.2018