【发布时间】:2018-12-28 00:19:07
【问题描述】:
我正在分析本质上是呼吸波形,以 3 种不同的形状构造(数据来自 MRI,因此使用了多个回波时间;如果您想了解一些快速背景知识,请参阅 here)。以下是在某些情况下绘制的两个波形的几个片段:
对于每个波形,我都在尝试执行 DFT 以发现主要频率或呼吸频率。
我的问题是,当我绘制我执行的 DFT 时,我会得到两件事之一,这取决于我使用的 FFT 库。此外,它们都不能代表我的预期。我知道数据并不总是我们想要的样子,但我的数据中显然存在波形,所以我希望是离散的傅里叶变换以在合理的地方产生频率峰值。作为参考,我预计大约 80 到 130 Hz。
我的数据存储在pandas 数据框中,每个回显时间的数据都在一个单独的系列中。我正在应用选择的 FFT 函数(参见下面的代码)并为每个函数接收不同的结果。
SciPy (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
NumPy:
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()
DFT 后 (SciPy fftpack):
后 DFT (NumPy)
Here 是指向用于创建这些图的数据集(在 Dropbox 上)的链接,here 是指向 Jupyter Notebook 的链接。
编辑:
我使用了发布的建议并获取了数据的大小(绝对值),并且还绘制了对数 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()
【问题讨论】:
-
实际上在您发布之前就发现了这一点。在编辑中修复。谢谢!
-
输入序列的平均值是多少?这些图显示的值约为 0.99,但垂直轴标签显示“标准化”。图是否代表传递给 FFT 函数的实际数据?
-
使用傅里叶变换,您通常对实部和虚部不感兴趣(除非您确实需要相位信息)。所以你应该考虑复数值的大小。这是给定频率的“能量”,它将帮助您确定哪些频率对信号的贡献最大。另一件事是信号具有平均值,因此零频率(即常数)很重要,并且主导其他频率的贡献。减去信号的平均值或使用对数 y 尺度。
-
附带问题...您引用的链接 mriquestions.com 是否提供类似于您在上面绘制的示例数据集文件?
-
@ScottStensland 可能没有;我的数据集来自专有的 MR 扫描仪。如果有帮助,我可以提供给您
标签: python numpy scipy fft dft