【问题标题】:How to interpret this fft graph如何解释这个 fft 图
【发布时间】:2020-05-09 07:46:29
【问题描述】:

我想将使用fft 函数的傅里叶变换应用于我的时间序列数据,以通过提取观察数据中的主要频率分量来查找“模式”,即。在每个时间序列结束时预测 y 值(细菌计数)的最低 5 个主要频率。 我想保留最小的 5 个系数作为特征,并消除其余的。

我的代码如下:

df = pd.read_csv('/content/drive/My Drive/df.csv', sep=',') 
X = df.iloc[0:2,0:10000]

dft_X = np.fft.fft(X) 
print(dft_X) 
print(len(dft_X))
plt.plot(dft_X)
plt.grid(True)
plt.show()

# What is the graph about(freq/amplitude)? How much data did it use? 
for i in dft_X: 

    m = i[np.argpartition(i,5)[:5]]
    n = i[np.argpartition(i,range(5))[:5]]

print(m,'\n',n)

这是输出:

但我不知道如何解释这个图表。准确地说,

1) 图表是否显示输入数据的转换值?我只用了2行数据(每行是一个时间序列),所以数据是2x10000,为什么图中有这么多行?

2) 要获得频率值,我应该使用np.fft.fftfreq(n, d=timestep)吗?

参数:
n : 整数 窗口长度。

d : 标量,可选 采样间隔(采样率的倒数)。默认为 1。

返回:
f : 数组 包含样本频率的长度为 n 的数组。

如何确定n(窗口长度)和sample spacing

3) 为什么转换后的值都是复数?

谢谢

【问题讨论】:

    标签: python numpy scipy signal-processing fft


    【解决方案1】:

    我会按照你的问题的相反顺序回答

    3) 为什么转换后的值都是复数?

    傅里叶变换的输出总是复数。为了解决这个问题,您可以在变换的输出上应用绝对值,或者只使用以下方法绘制实部:

    plt.plot(dft_X.real)
    

    2) 要获得频率值,我应该使用 np.fft.fftfreq(n, d=timestep) 吗?

    不,“频率值”将在 FFT 的输出上可见。

    1) 图表是否显示输入数据的转换值?我只用了2行数据(每行是一个时间序列),所以数据是2x10000,为什么图中的线这么多?

    您的图表有这么多线,因为它为数据集的每一列画了一条线。分别对每一行应用 FFT(或者可能只是转置您的数据帧),然后您将获得更多实际的频域图。


    跟进

    将输出的绝对值或实部用作以后模型的特征与使用原始输出的效果会不同吗?

    绝对值通常更容易使用。

    使用实部 使用绝对值 这是生成此代码的 Octave 代码:

    Fs = 4000;                          % Sampling rate of signal
    T  = 1/Fs;                          % Period
    L  = 4000;                          % Length of signal
    t  = (0:L-1)*T;                     % Time axis
    
    freq = 1000;                        % Frequency of our sinousoid
    
    sig   = sin(freq*2*pi*t);           % Fill Time-Domain with 1000 Hz sinusoid
    f_sig = fft(sig);                   % Apply FFT
    
    f = Fs*(0:(L/2))/L;                 % Frequency axis
    
    figure
      plot(f,abs(f_sig/L)(1:end/2+1));  %      peak at 1kHz)
    figure 
      plot(f,real(f_sig/L)(1:end/2+1)); % main peak at 1kHz)
    

    在我的示例中,您可以看到绝对值在我生成的频率为 1kHz 的正弦曲线以外的频率上没有返回任何噪声,而实部在 1kHz 处具有更大的峰值,但也有更多的噪声。

    至于效果,我不知道你的意思。

    是否期望“频率值”总是复数

    总是?不会。傅里叶级数表示正弦和余弦之和完全等同于任何连续周期函数的频率系数。正弦和余弦可以通过欧拉公式写成复杂的形式。这是存储傅里叶系数最方便的方法。事实上,频域信号的虚部代表信号的相位。 (即,如果我有 2 个相同频率的正弦函数,它们可以有不同的复数形式,具体取决于时移)。但是,大多数提供 FFT 函数的库默认将 FFT 系数存储为复数,以便于相位和幅度计算。

    FFT 在绘制一条线时是否使用数据集的每一列

    我认为这是 mathplotlib.plot 的问题,而不是 np.fft。

    你能告诉我如何分别对每一行应用 FFT

    有很多方法可以解决这个问题,我不想强​​迫您走一条路,因此我将提出通用解决方案来遍历数据帧的每一行并在每个特定行上应用 FFT。否则,在您的情况下,我相信转置您的输出也可以工作。

    【讨论】:

    • 感谢您的回答。根据您的订单,我确实有一些进一步的问题:3)使用输出的绝对值或实部作为以后模型的特征与使用原始输出有不同的效果吗? 2)“频率值”将在 FFT 的输出上可见-根据您对 3)的解释,是否期望“频率值”总是复数?你能解释一下为什么它有意义吗? 1) FFT 在绘制一条线时是否使用数据集的每一列?你能告诉我如何在每一行分别应用FFT吗?非常感谢
    • @nilsinelabore 编辑了我的回复以回答您的问题
    • 很棒的答案。谢谢 :) 如果在 FFT 的输出上可以看到“频率值”,numpy.fft.fftnumpy.fft.fftfreq 有什么区别?
    • @nilsinelabore 我错了,numpy.fft.fftfreq 将为您提供长度为n 的信号的频率轴值。我不知道您是如何获取数据的,但如果您知道采样率,您可以将其反转并将其作为d 提供给numpy.fft.fftfreqfftfftfreq 之间的区别在于 fft 将返回您的信号变换,但要准确知道您的峰值所在的频率,您需要 fftfreq 将您的 fft 值与产生的频率。
    • @nilsinelabore 如果您知道信号的持续时间,那么采样率将为Fs =(# of samples)/(Duration),因为您正在寻找d,无论如何您可以快捷方式到d = (Duration)/(# of samples)。如果您没有关于信号持续时间的任何信息,您将无法知道采样率。如果你不这样做,我建议你问问你的数据来源。
    猜你喜欢
    • 2010-11-19
    • 2022-01-05
    • 2018-12-31
    • 2022-12-14
    • 2022-06-15
    • 2015-10-11
    • 2018-04-02
    • 2010-10-15
    • 2012-03-17
    相关资源
    最近更新 更多