【问题标题】:Numpy fft not giving expected resultsNumpy fft没有给出预期的结果
【发布时间】:2018-12-08 07:58:30
【问题描述】:

我正在尝试在由 100Hz PWM 驱动器驱动的螺线管的电流信号中找到频谱。信号以 19200 Hz 采样。

以下是信号图。该信号是较长时间序列数据的一部分。从 22 秒点中提取 1024 个数据点。

Current Signal

以下代码用于分析

import numpy as np
import matplotlib.pyplot as plt

plt.figure(1)
plt.plot(t,y)

Fs=19200              # (Hz) sampling rate
N=len(y)   # length of signal
time=N/Fs #total time of signal, 1/time is the fundamantal frequency
freq=np.arange(N)/time  # frequency vector for fft spectrum plot
freq=freq[0:int(N/2)]  # one sided frequecy
Y=np.fft.fft(y)/N*2     # fft of signal
Y=Y[0:int(N/2)]         # one sided frequency

plt.figure(2)
plt.plot(freq,abs(Y))  # one sided frequency plot

plt.xlabel("Hz")
plt.ylabel("Units")
plt.title("FFT spectrum")
plt.grid()
plt.show()

人们会期望频谱中占主导地位的 100 Hz 分量,但 numpy fft 结果并未反映这一点。以下是numpy.fft 频率图。

FFT Spectrum

以下是类似信号的 Matlab fft 分析图。正如预期的那样,有一个占主导地位的 100Hz 分量和谐波。

Signal for Matlab fft analysis

Matlab FFT spectrum

【问题讨论】:

  • 显然第二张图片只是您的数据,但比例不同。没有计算 fft。如果您没有输入 y 而不是 Y,请检查您的代码。这里没有错字,但这是唯一的解释
  • 请始终运行您在此处发布的代码。发布的代码显然没有生成给定的图表。阅读更多相关信息:minimal reproducible example
  • 我已经用测试数据信号(T=1, t=np.arange(0,T,1/Fs), y=2 + 4*np.sin(3*) 测试了代码2*np.pit)+13*np.sin(9*2*np.pit) 和 numpy fft 正确识别具有相应幅度的 2 和 3Hz 和 9Hz 正弦分量的 DC 分量. 我不确定为什么在当前信号上没有正确计算 fft。

标签: python numpy scipy fft


【解决方案1】:

我建议您对您已经知道分析结果的函数执行离散傅里叶变换。一旦您对所看到的内容感到满意,就可以在您不知道结果的内容上运行一些代码行,就像我在本次讨论中所做的那样

Numerical Fourier Transform of rectangular function

如您所见,在 Matlab 和 Python 中,都必须在数值傅里叶变换之前和之后执行频谱右侧的移动 ( fftshift(y) )。

您可能还对所谓的奈奎斯特定理感兴趣,该定理说明了可以应用数值傅里叶变换的最小采样频率,但我认为目前这不是您的问题,因为采样频率你的光谱看起来很高。

顺便说一下,使用python对阶跃函数执行快速傅里叶变换的正确方法如下所述

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(-3, 3, 0.01)
y = np.zeros(len(x))
y[200:400] = 1
# Step function for which the Fourier Transform is well known to be sin(x)/x
yShift = np.fft.fftshift(y) 
# Shift of the N/2 sampling data on the right side to the left side
fftyShift = np.fft.fft(yShift)
# Numerical Fourier Transform (Lanczos)
ffty = np.fft.fftshift(fftyShift)
# Shift of the N/2 transformed data on the right side to the left side

plt.plot(ffty)
plt.show()

【讨论】:

  • FFT前需要使用ifftshift对信号进行移位。如果信号长度为奇数,则此函数与fftshift 不同。此外,仅当原点被明确定义在信号的中心而不是左边缘时才需要使用它。 fftshift 在 FFT 之后同样只有当人们想在绘图中间看到零频率时才需要,一般来说根本没有必要。 -- 也就是说,这并不能真正回答问题,因为 OP 根本没有应用 FFT。
  • 感谢您的回答 Stefano。但它仍然没有解决问题。
猜你喜欢
  • 2021-08-31
  • 2020-05-29
  • 1970-01-01
  • 2019-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-09
  • 1970-01-01
相关资源
最近更新 更多