【问题标题】:How to get correct phase values using numpy.fft如何使用 numpy.fft 获得正确的相位值
【发布时间】:2019-04-12 15:11:24
【问题描述】:
import numpy as np 
import matplotlib.pyplot as plt 

n = 500
T = 10
dw = 2 * np.pi / T

t = np.linspace(0, T, n)
x = 5 * np.sin(20 * t + np.pi)  + 10 * np.sin( 40 * t + np.pi/2)

fftx = np.fft.rfft(x)
freq = np.fft.rfftfreq(n) * n * dw

amps = np.abs(fftx) * 2 /  n
angs = np.angle(fftx) 


_, ax = plt.subplots(3, 1)
ax[0].plot(t, x)
ax[1].plot(freq, amps)
ax[2].plot(freq, angs)

我得到正确的频率和幅度值。但从图中可以看出,相位值不正确。如何从fft中提取正确的相位值?我在相位图中究竟看到了什么?

我预计频率 20 和 40 分别约为 3.14 和 3.14/2。

【问题讨论】:

    标签: numpy fft


    【解决方案1】:

    计算相位有两个问题:

    1. 您的输入信号不是整数个周期。如果重复复制信号,您会发现实际上有一组与构建信号时所假设的频率分量不同的频率分量(DFT 可以被认为是使用信号的无限重复作为输入)。这会导致峰有一定的宽度,也会导致相位发生一点偏移。

      您可以通过将信号加窗或创建信号使其具有整数个周期来解决此问题。后者是:

      T = 3 * np.pi
      t = np.linspace(0, T, n, endpoint=False)
      
    2. 没有信号的频率(经过上面的修复后都是除了两个频率),相位将由噪声给出。您可以在此处将相位设置为零:

      angs[amps < 1] = 0
      

    现在你的情节看起来像这样:

    相位与您预期的不同,因为正弦的相位为 -π/2。使用cos 而不是sin 重复实验,您将得到您所期望的阶段。

    【讨论】:

    • 酷。那行得通。 > integer number of periods 如果我不知道我在分析什么信号,我该如何获得?我是否只需添加dt = ceil(T/pi) * pi - T 来创建新的T?或者在这种情况下,开窗是我唯一的选择? (我不知道什么是真正的窗口)。
    • @Pratik:是的,如果您的信号不是合成的,那么唯一合适的方法是加窗。在Wikipedia page for window function 上有很多关于它的信息。简而言之,只需在 FFT 之前将信号与 Hann 窗相乘即可。
    • 明白了!谢谢!
    • @Pratik:如果我理解正确,您将信号长度设为 pi 的倍数。但是,如果您不知道信号周期是什么,您就无法做到这一点。还有:如果信号周期不是采样周期的倍数怎么办?在现实世界的信号中,您无法选择可以为您提供完美 FFT 的窗口长度。窗口是去那里的方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-25
    • 2022-09-27
    • 2016-03-30
    • 2012-02-02
    • 1970-01-01
    相关资源
    最近更新 更多