您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

在python中将FFT绘制为一组正弦波?

在python中将FFT绘制为一组正弦波?

离散傅立叶变换可为您提供复指数的系数,这些系数相加在一起可产生原始离散信号。特别是,第k个傅里叶系数可为您提供有关在给定数量的样本上具有k个周期的正弦波振幅的信息。

请注意,由于您的正弦波在1000个样本中没有整数个周期,因此实际上您将无法使用FFT检索原始正弦波。相反,您将得到许多不同正弦曲线的混合体,包括?.4的恒定分量。

您可以使用以下代码绘制各种分量正弦曲线,并观察它们的和为原始信号:

freqs = np.fft.fftfreq(len(x),.01)
threshold = 0.0
recomb = np.zeros((len(x),))
for i in range(len(fft3)):
    if abs(fft3[i])/(len(x)) > threshold:
        recomb += 1/(len(x))*(fft3[i].real*np.cos(freqs[i]*2*np.pi*x)-fft3[i].imag*np.sin(freqs[i]*2*np.pi*x))
        plt.plot(x,1/(len(x))*(fft3[i].real*np.cos(freqs[i]*2*np.pi*x)-fft3[i].imag*np.sin(freqs[i]*2*np.pi*x)))
plt.show()

plt.plot(x,recomb,x,sin3)
plt.show()

通过更改threshold,您还可以选择排除低功率的正弦波,并查看其如何影响最终的重建。

编辑:上面的代码中有一个陷阱,尽管它没有错。它隐藏了DFT对于真实信号的固有对称性,并以其真实幅度的一半绘制了每个正弦曲线两次。此代码性能更高,并以正确的幅度绘制正弦曲线:

freqs = np.fft.fftfreq(len(x),.01)
threshold = 0.0
recomb = np.zeros((len(x),))
middle = len(x)//2 + 1
for i in range(middle):
    if abs(fft3[i])/(len(x)) > threshold:
        if i == 0:
            coeff = 2
        else:
            coeff = 1
        sinusoid = 1/(len(x)*coeff/2)*(abs(fft3[i])*np.cos(freqs[i]*2*np.pi*x+cmath.phase(fft3[i])))
        recomb += sinusoid
        plt.plot(x,sinusoid)
plt.show()

plt.plot(x,recomb,x,sin3)
plt.show()

在一般情况下,如果您知道信号是由一些正弦波子集组成的,这些子集的频率可能与信号的长度未正确对齐,则可以通过零填充或扩展信号来识别频率。您可以@L_301_0@了解更多信息。如果信号是完全任意的,而您只是对查看分量正弦波感兴趣,则无需这样做。

python 2022/1/1 18:26:35 有752人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶