【问题标题】:scipy Fast fourier transform doesn't recognize the signalscipy 快速傅立叶变换无法识别信号
【发布时间】:2022-01-02 17:07:37
【问题描述】:

我正在尝试通过傅立叶变换获取信号的频率,但它无法识别它(将峰值设置为 f=0)。也许我的代码有问题(页面末尾的完整代码):

PF = fft.fft(Y[0,:])/Npoints #/Npoints to get the true amplitudes
ZF = fft.fft(Y[1,:])/Npoints
freq = fft.fftfreq(Npoints,deltaT)
PF = fft.fftshift(PF) #change of ordering so that the frequencies are increasing
ZF = fft.fftshift(ZF)
freq = fft.fftshift(freq)
plt.plot(freq, np.abs(PF))
plt.show()
plt.plot(T,Y[0,:])
plt.show()

其中 Npoints 是间隔(点)的数量,而 deltaT 是间隔的时间间隔。可以看到峰值在 f=0

我还展示了 Y[0,:](我的信号)随时间变化的图,很明显信号具有特征频率

完整的可重复代码

import numpy as np 
import matplotlib.pyplot as plt
#numerical integration
from scipy.integrate import solve_ivp
import scipy.fft as fft

r=0.5
g=0.4
e=0.6
H=0.6
m=0.15
#define a vector of K between 0 and 4 with 50 componets
K=np.arange(0.1,4,0.4)

tsteps=np.arange(7200,10000,5)
Npoints=len(tsteps)
deltaT=2800/Npoints #sample spacing
for k in K :
    i=0
    def RmAmodel(t,y):
        return [r*y[0]*(1-y[0]/k)-g*y[0]/(y[0]+H)*y[1], e*g*y[0]/(y[1]+H)*y[1]-m*y[1]]

    sol = solve_ivp(RmAmodel, [0,10000], [3,3], t_eval=tsteps) #t_eval specify the points where the solution is desired
    T=sol.t
    Y=sol.y
    vk=[]
    for i in range(Npoints):
        vk.append(k)
    XYZ=[vk,Y[0,:],Y[1,:]]
    #check periodicity over P and Z with fourier transform

    
    
#try Fourier analysis just for the last value of K        
    PF = fft.fft(Y[0,:])/Npoints #/Npoints to get the true amplitudes
    ZF = fft.fft(Y[1,:])/Npoints
    freq = fft.fftfreq(Npoints,deltaT)
    PF = fft.fftshift(PF) #change of ordering so that the frequencies are increasing
    ZF = fft.fftshift(ZF)
    freq = fft.fftshift(freq)
    plt.plot(T,Y[0,:])
    plt.show()
    plt.plot(freq, np.abs(PF))
    plt.show()

【问题讨论】:

  • 建议您发布一个带有数据的最小可重现示例
  • fft 结果是复数。您需要在绘图之前获取它们的绝对值。此外,您提供的代码还不够。那是什么T
  • @AbdurRakib 抱歉,我忘记了一些代码,现在已编辑。我绘制了 fft 的绝对值。 T 是与信号相关的时间步长的数组,在最后一个图中使用
  • @MitchWheat 我在底部报告了完整代码,因此可以使用数据运行它
  • f=0 处分量的幅度是信号的mean(即“DC 分量”)。查看数据图;平均值约为 1.342。现在查看 FFT 结果图中尖峰的大小。信号的正弦分量的幅度都远小于 1.342,因此直流分量占主导地位。

标签: python signal-processing fft continuous-fourier


【解决方案1】:

我无法确定问题出在哪里。 fft 代码中似乎存在一些问题。反正我时间不多,就放一个我之前做的示例代码。您可以将其用作参考或复制粘贴。它应该可以工作。

import numpy as np
import matplotlib.pyplot as plt
from scipy.fft import fft, fftfreq

fs = 1000   #sampling frequency
T = 1/fs    #sampling period
N = int((1 / T) + 1) #number of sample points for 1 second
t = np.linspace(0, 1, N) #time array
pi = np.pi

sig1 = 1 * np.sin(2*pi*10*t)
sig2 = 2 * np.sin(2*pi*30*t)
sig3 = 3 * np.sin(2*pi*50*t)
#generate signal
signal = sig1 + sig2 + sig3
#plot signal
plt.plot(t, signal)
plt.show()

signal_fft = fft(signal)    #getting fft
f2 = np.abs(signal_fft / N) #full spectrum
f1 = f2[:N//2]              #half spectrum
f1[1:] = 2*f1[1:]           #actual amplitude

freq = fs * np.linspace(0,N/2,int(N/2)) / N     #frequency array
#plot fft result
plt.plot(freq, f1)
plt.xlim(0,100)
plt.show()

【讨论】:

  • 你的代码也只给出了 0 峰值
猜你喜欢
  • 1970-01-01
  • 2018-11-21
  • 1970-01-01
  • 1970-01-01
  • 2011-07-12
  • 2011-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多