Matlab与Numpy(Python)的FFT结果:不同的结果

Matlab与Numpy(Python)的FFT结果:不同的结果,python,matlab,numpy,fft,Python,Matlab,Numpy,Fft,我有一个Matlab脚本来计算信号的DFT并绘制它: (可以找到数据) 我正在尝试将其转换为Python,但无法得到相同的结果 将numpy导入为np 从matplotlib导入pyplot作为plt x=np.genfromtxt(“s.txt”,分隔符=“”) nfft=100 fs=24000 deltaF=fs/nfft; ffft=[n*范围内n的deltaF(nfft/2-1)] ffft=np.数组(ffft) 窗=np.hanning(透镜(x)) xw=np.乘法(x,窗口)

我有一个Matlab脚本来计算信号的DFT并绘制它:

(可以找到数据)

我正在尝试将其转换为Python,但无法得到相同的结果

将numpy导入为np
从matplotlib导入pyplot作为plt
x=np.genfromtxt(“s.txt”,分隔符=“”)
nfft=100
fs=24000
deltaF=fs/nfft;
ffft=[n*范围内n的deltaF(nfft/2-1)]
ffft=np.数组(ffft)
窗=np.hanning(透镜(x))
xw=np.乘法(x,窗口)
fft=np.fft.fft(xw,nfft)/len(x)
fft=fft[0]+[2*fft[1:nfft/2]]
fftabs=20*np.log10(np.absolute(fft))
plt.图()
plt.绘图(ffft,np.转置(fftabs))
plt.grid()
我得到的图(Matlab在左边,Python在右边):


我做错了什么?

我不是Mathlab用户,所以我不确定,但我想问几件事,看看我是否能帮助你

您在创建数组后调用了np.array(ffft)。这可能不会像您希望的那样改变数组的性质,也许最好尝试在
np.array中定义它(n*deltaF表示范围内的n(nfft/2-1))
我不确定格式,但您明白了。另一件事是我觉得这个范围不合适。你想让它的值为49

另一个是
fft=fft[0]+[2*fft[1:nfft/2]]
fft=[fft(1);2*fft(2:nfft/2)]我不确定比较是否准确。对我来说,这只是一种不同的定义

此外,当我进行这些类型的计算时,我会“打印”出中间步骤,这样我就可以比较这些数字,看看它们在哪里断裂


希望这能有所帮助。

在一种情况下,两个代码是不同的,您可以将两个列表连接起来

FFT = [FFT(1); 2*FFT(2:nFFT/2)];
在matlab代码中

在另一种情况下,将fft的第一个值与向量的其余部分相加

fft = fft[0]+ [2*fft[1:nfft/2]]
“+”不要在此处连接,因为您有numpy数组

在python中,它应该是:

fft = fft[0:nfft/2]
fft[1:nfft/2] =  2*fft[1:nfft/2]

我发现使用
np.fft.rfft
而不是
np.fft.fft
并按以下方式修改代码可以完成工作:

import numpy as np
from matplotlib import pyplot as pl

x = np.genfromtxt("../Matlab/s.txt", delimiter='  ')

nfft = 100
fs = 24000
deltaF = fs/nfft;
ffft = np.array([n * deltaF for n in range(nfft/2+1)])
window = np.hanning(len(x))

xw = np.multiply(x, window)
fft = np.fft.rfft(xw, nfft)/len(x)
fftabs = 20*np.log10(np.absolute(fft))

pl.figure()
pl.plot(np.transpose(ffft), fftabs)
pl.grid()
结果图:


我可以看到第一个点和最后一个点,以及振幅都不一样。这对我来说不是问题(我对一般形状更感兴趣),但如果有人能解释,我会很高兴。

可能不是你的主要问题,但你的窗口函数应该与FFT大小相同,即nfft,而不是len(x)(适用于MATLAB和Python代码)。@Paul R有趣,我在哪里可以找到更多关于这方面的信息?这里有很多关于StackOverflow的问题和答案,涉及窗口功能和FFT。不过,最基本的一点是,您对FFT的输入数据应用了一个参数,以便减少。因此,此窗口函数的大小需要与FFT的大小匹配。这不太可能是问题所在,但请注意,matlab的
[0:49]
与python的
范围(49)
不同。在python中,你只差一步。(即
范围(49)
相当于
[0:48]
)谢谢。我这样更改了ffft的定义:
ffft=np.array(n*deltaF表示范围内的n(nfft/2-1))
。你提到的代码的第二部分也不确定。我找到了一个解决方案,将在下面发布。我也不在乎我能拿到多少分。我可能会用不同的值做一些测试。
import numpy as np
from matplotlib import pyplot as pl

x = np.genfromtxt("../Matlab/s.txt", delimiter='  ')

nfft = 100
fs = 24000
deltaF = fs/nfft;
ffft = np.array([n * deltaF for n in range(nfft/2+1)])
window = np.hanning(len(x))

xw = np.multiply(x, window)
fft = np.fft.rfft(xw, nfft)/len(x)
fftabs = 20*np.log10(np.absolute(fft))

pl.figure()
pl.plot(np.transpose(ffft), fftabs)
pl.grid()