代码之家  ›  专栏  ›  技术社区  ›  bearplane

使用python时出现意外的fft结果

  •  2
  • bearplane  · 技术社区  · 6 年前

    我正在分析什么本质上是呼吸波形,以3种不同的形状构造(数据来源于MRI,因此使用了多次回波时间;请参见 here if you'd like some quick background)。下面是一些上下文中两个绘制的波形的几个片段:

    对于每个波形,我都在尝试执行DFT,以发现呼吸的主要频率。

    我的问题是,当我绘制我执行的DFT时,我得到了两件事情中的一件,这取决于我使用的FFT库。此外, 两者都不能代表我所期望的。 我了解数据并不总是按照我们所希望的方式显示,但我的数据中显然存在波形,因此我希望使用离散傅立叶变换在某个合理的地方产生频率峰值。作为这里的参考,我预计大约80到130赫兹。

    我的数据存储在一个 pandas data frame中,每个echo time的数据都在一个单独的序列中。我正在应用选择的fft函数(请参见下面的代码),并为每个函数接收不同的结果。

    scipy( fftpack )

    导入熊猫为pd 导入scipy.fftpack #临时复制以维护数据结构 lead_pts_fft_df=lead_pts_df.copy()) #对数据帧中的每个数据序列应用离散快速傅立叶变换 Lead_pts_fft_df.large=Lead_pts_df.large.apply(scipy.fftpack.fft) 铅弹

    数字:

    导入熊猫为pd 将numpy导入为np #临时复制以维护数据结构 lead_pts_fft_df=lead_pts_df.copy()) #对数据帧中的每个数据序列应用离散快速傅立叶变换 Lead_pts_fft_df.large=Lead_pts_df.large.apply(np.fft.fft) 铅弹

    其余相关代码:

    echo_times=[0.080,0.200,0.400]毫秒
    
    F_s=1/(0.006)0.006=样品之间的时间
    freq=np.linspace(0,29556,29556)*(f_s/29556)(29556=数据长度)
    
    #生成子批次
    图,轴=plt.子图(3,1,FigSize=(18,16))
    
    对于范围内的IDX(长度(回声时间)):
    轴[IDX].绘图(freq,lead_pts_fft_df.large[IDX].real,real part
    freq,lead_pts_fft_df.量级[idx].imag,虚部
    
    轴[IDX].Legend()对每组轴应用图例
    
    #显示绘图
    请显示())
    

    后DFT(scipyfftpack):

    后干膜厚度(numpy)

    hereis a link to the dataset(on dropbox)used to create these plots,and这里是Jupyter笔记本的链接。

    编辑:

    我使用张贴的建议,并采取的幅度(绝对值)的数据,也绘制了对数y轴。新结果发布在下面。我的信号好像有点模糊。我是否使用了正确的频率刻度?更新后的代码和绘图如下。

    生成子批次 图,轴=plt.子图(3,1,FigSize=(18,16)) 对于范围内的IDX(长度(回声时间)): 轴[IDX].plot(freq[1::]、np.log(np.abs(lead-pts-fft-df.large[IDX][1::]), label=lead_pts_df.index[idx],应用标签 颜色=绘图颜色[IDX]颜色 轴[IDX].Legend()对每组轴应用图例 #显示绘图 请显示())

    
    

    =here如果你想快速了解背景的话)。以下是一些上下文中两个绘制波形的几个片段:

    enter image description here

    对于每一个波形,我都试图执行一个DFT,以发现呼吸的主要频率。

    我的问题是,当我绘制我执行的DFT时,我得到了两件事情中的一件,这取决于我使用的FFT库。此外,它们都不能代表我所期待的。我知道数据并不总是按照我们想要的方式显示,但我的数据中显然存在波形,所以我希望离散傅立叶变换在某个合理的地方产生一个频率峰值。作为参考,我预计大约80到130赫兹。

    我的数据存储在pandas数据帧,每个回波时间的数据在一个单独的序列中。我正在应用选择的fft函数(见下面的代码),并为每个函数接收不同的结果。

    坐骨神经痛(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()
    

    后干膜厚度(scipyFFT背包):

    enter image description here

    后干膜厚度(numpy)

    enter image description here

    Here是指向用于创建这些绘图的数据集(在Dropbox上)的链接,以及here是指向Jupyter笔记本的链接。

    编辑:

    我使用张贴的建议,并采取的幅度(绝对值)的数据,也绘制了对数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()
    

    1 回复  |  直到 6 年前
        1
  •  1
  •   bearplane    6 年前

    scipy.signal.detrend()

    # import DFT and signal packages from SciPy
    import scipy.fftpack
    import scipy.signal
    
    # temporary copy to maintain data structure; original data frame is NOT changed due to ".copy()"
    lead_pts_fft_df = lead_pts_df.copy()
    
    # apply a discrete fast Fourier transform to each data series in the data frame AND detrend the signal
    lead_pts_fft_df.magnitude = lead_pts_fft_df.magnitude.apply(scipy.signal.detrend)
    lead_pts_fft_df.magnitude = lead_pts_fft_df.magnitude.apply(np.fft.fft)
    lead_pts_fft_df
    

    num_projections = 29556
    N = num_projections
    T = (6 * 3) / 1000 # 6*3 b/c of the nature of my signal: 1 pt for each waveform collected every third acquisition
    xf = np.linspace(0.0, 1.0 / (2.0 * T), num_projections / 2)
    

    # generate subplots
    fig, axes = plt.subplots(3, 1, figsize=(18, 16))
    
    for idx in range(len(ECHO_TIMES)):
        axes[idx].plot(xf, 2.0/num_projections * np.abs(lead_pts_fft_df.magnitude[idx][:num_projections//2]),
                       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()
    

    enter image description here