python - Python FFT:频移
问题描述
在对信号进行频谱分析时,我遇到了一个奇怪的问题,即绘制的信号频率发生了偏移(或加倍)。这是一个显示我的方法的简单示例:以 100kHz 采样 1kHz 正弦信号。最后,信号仓出现在 2kHz 而不是 1kHz。
import numpy as np
import matplotlib.pyplot as plt
time_step = 1.0/100e3
t = np.arange(0, 2**14) * time_step
sig = np.sin(2*np.pi*1e3*t)
sig_fft = np.fft.rfft(sig)
#calculate the power spectral density
sig_psd = np.abs(sig_fft) ** 2 + 1
#create the frequencies
fftfreq = np.fft.fftfreq(len(sig_psd), d=time_step)
#filter out the positive freq
i = fftfreq > 0
plt.plot(fftfreq[i], 10*np.log10(sig_psd[i]))
plt.xscale("log")
解决方案
您使用错误的函数来计算频率。实信号的 FFT 变换具有负频率分量,它们是正频率分量的复共轭,即频谱是 Hermitian 对称的。rfft()
利用这一事实,不输出负频率,只输出直流分量和正频率。因此,如果您使用而不是传递它以有效地使频率加倍,则它的sig_psd
长度是您将得到的长度的两倍。fft()
rfft()
fftfreq()
解决方法:rfftfreq()
改用。
import numpy as np
import matplotlib.pyplot as plt
time_step = 1.0/100e3
t = np.arange(0, 2**14) * time_step
sig = np.sin(2*np.pi*1e3*t)
sig_fft = np.fft.rfft(sig)
#calculate the power spectral density
sig_psd = np.abs(sig_fft) ** 2 + 1
#create the frequencies
fftfreq = np.fft.rfftfreq(len(sig), d=time_step) # <-- note: len(sig), not len(sig_psd)
#filter out the positive freq
i = fftfreq > 0 # <-- note: Not really needed, this just removes the DC component
plt.plot(fftfreq[i], 10*np.log10(sig_psd[i]))
plt.xscale("log")
推荐阅读
- mysql - 为什么这个查询不解析?
- google-cloud-nl - 谷歌云 PHP 自然语言在句子中查找日期
- linux - 如何安装 Jenkins Ubuntu slave 作为服务?
- google-cloud-platform - Terraform 是否能够管理角色/所有者绑定和成员资格?
- java - iOS 和 Android AES 加密(Java 中没有 UINT)
- c++ - C++/CLI 前向声明 - 相互依赖的类
- c# - 我可以获得电子窗口的 MainWindowHandle 吗?
- c++ - 使用全局 QObject 进行交叉信号/插槽转发是正确的方法
- xcode - 为 Interface Builder 添加自定义对齐线到 UIView
- http - 如何在邮递员中进行跟踪请求