如何从在Python中执行FFT后获得的复数集中获取频率幅度?
我不知道在对一个wav文件进行快速傅里叶变换(FFT)后,得到一组复杂数字后该怎么做。怎样才能得到对应的频率呢?下面是我进行FFT后得到的输出结果:
[ 12535945.00000000 +0.j -30797.74496367 +6531.22295858j
-26330.14948055-11865.08322966j ..., 34265.08792783+31937.15794965j
-26330.14948055+11865.08322966j -30797.74496367 -6531.22295858j]
3 个回答
如果我没记错的话,频率可以通过计算复数的大小来得到。所以对每个复数简单地用 abs(x)
这个函数,就能得到频率。
正如 @KennyTM 在重复问题中已经解释的那样:
频率是由数组的 索引 决定的。每个元素对应一个频率。
要确定每个元素代表的频率,你需要知道你的数据的采样频率和数组的长度。
基本上,它的计算方式大概是这样的:
sampling_freq = 1000.0 # in Hz
freq = np.linspace(0, (1.0 / sampling_freq / 2.0), (x.size / 2) + 1)
对于 fft 数组的一半(它在中心是对称的)。不过我记得有点模糊,所以可能不太准确……
无论如何,numpy 有一个辅助函数可以帮你完成这个计算:numpy.fft.fftfreq
其实,abs(x)这个操作只是把你结果列表中的一个实数和虚数对转换成一个大小值。你可以这样做,除非你想保留虚数部分以备将来使用。转换后,结果列表中的每个数字代表你频谱中某个频率的信号大小。所以,频率是通过列表的索引来表示的。当你在XY图上绘制数据时,你看到的就是你的源信号包含的频率大小。别忘了,只有你数据的前半部分是有效的。后半部分通常是前半部分的镜像,原因是混叠现象。
举个例子,假设你对一个采样频率为10Khz的wav文件进行了1024点的快速傅里叶变换(FFT)。FFT会把这个10Khz的频谱分成1024个“箱子”。然后,FFT会判断每个频谱块在源wav文件中有多少。你的输出应该就是这些箱子。通常我在做频率分析时,实际得到的数字并不是最重要的,我更关心的是这些大小相对于周围箱子的关系。
再详细一点,我们依赖于叠加原理,这个原理说明任何包含多种频率的随时间变化的信号都可以分解成多个只包含单一频率的信号,反之亦然。所以FFT的输出反映了这个特性。你输出列表中的每个值代表一个单一频率(通常称为“箱子”)的信号大小,这个信号在你的源信号中存在。把所有这些信号组合在一起,你应该能得到你的源信号。
哦,如果你不知道的话,由于奈奎斯特定律(或规则,不太确定),你结果列表的前半部分才是有效的。这个定律说所有采样系统只能重现频率不超过采样频率一半的信号。所以如果你以10Khz采样一个信号,你只能从采样数据中重现最高5Khz的频率。这个原理也是为什么你的FFT数据只有前半部分是有效的原因,后半部分是前半部分的混叠。
抱歉解释得有点长,你的问题没有说明你有什么经验,所以我觉得有必要解释一下FFT的一般概念。