为什么scipy和numpy fft情节看起来不同?

fal*_*oso 5 python numpy fft scipy

我目前正在为一篇课程做一些频谱分析,尽管我们还没有明确地教过傅里叶变换.我一直在玩scipy和numpy中的各种fft算法的一些数据,我知道答案应该是什么样的

在这种情况下,它的AM信号在8kHz载波频率和1kHz调制正弦波在顶部,因此在fft上应该有3个清晰的峰值

申请时scipy.fftpack.rfft,numpy.fft.rfft我分别得到以下情节:

SciPy的:

在此输入图像描述

NumPy的:

在此输入图像描述

虽然2个FFT的形状与峰值之间的正确比率大致相同,但是numpy一个看起来更平滑,而scipy一个具有略小的最大峰值,并且具有更多的噪声.

我假设这很大程度上取决于离散傅里叶变换算法的不同应用,并且已经看到其他文章关于如何scipy在运行时更快地实现.但是我在徘徊是什么特别导致差异,哪一个实际上更准确?

编辑:用于生成图表的代码:

data = pd.read_csv("./Waveforms/AM waveform Sine.csv", sep = ',', dtype = float)

data = data.as_matrix()
time = data[:,0]
voltage = data[:,1]/data[:,1].max() # normalise the values

#scipy plot:
plt.figure()
magnitude =  scipy.fftpack.rfft(voltage)
freq = scipy.fftpack.rfftfreq(len(time),np.diff(time)[0])
plt.figure()
plt.plot(freq, np.absolute(magnitude), lw = 1)
plt.ylim(0,2500)
plt.xlim(0,15)

#numpy plot
magnitude = np.fft.rfft(voltage)
freq = np.fft.rfftfreq(len(time),np.diff(time)[0])

plt.figure()
plt.plot(freq, np.absolute(magnitude), lw = 1)
plt.ylim(0,2500)
plt.xlim(0,15)
Run Code Online (Sandbox Code Playgroud)

Pie*_*uyl 9

来自NumPy的rfft文档:

返回:

out:复杂的ndarray

截断或零填充输入,沿轴指示的轴转换,或者如果未指定轴,则转换为最后一个.如果n是偶数,则变换轴的长度是(n/2)+1.如果n为奇数,则长度为(n + 1)/ 2.

它没有明确写出,但"转换后的数据"在这里很复杂.

来自SciPy的rfft文档

z:真正的ndarray

返回的实数数组包含:

[y(0),Re(y(1)),Im(y(1)),...,Re(y(n/2))]              if n is even
[y(0),Re(y(1)),Im(y(1)),...,Re(y(n/2)),Im(y(n/2))]   if n is odd
Run Code Online (Sandbox Code Playgroud)

结论:存储是不同的.

对于起动器,看看magnitude它的长度,两种情况都会有所不同.为清楚起见,我在下面举例说明:

In [33]: data = np.random.random(size=8)

In [34]: np.fft.rfft(data)
Out[34]: 
array([ 3.33822983+0.j        ,  0.15879369+0.48542266j,
        0.00614876+0.03590621j, -0.67376592-0.69793372j,  1.51730861+0.j        ])

In [35]: scipy.fftpack.rfft(data)
Out[35]: 
array([ 3.33822983,  0.15879369,  0.48542266,  0.00614876,  0.03590621,
       -0.67376592, -0.69793372,  1.51730861])
Run Code Online (Sandbox Code Playgroud)

两种情况下的第一个元素是所谓的"DC分量"(信号的平均值).

然后,您可以在SciPy版本中识别NumPy版本的实部和虚部的连续性.

  • 将复数值存储在数组的连续元素中意味着在“np.fft.rfft”情况下,对数组“magnitude”进行“np.absolute”操作将给出复数值的范数(这是相关的物理量)。 amount),而对于“scipy.fftpack.rfft”情况,它将首先给出数字的实部的绝对值,然后仅给出复数分量的大小,并且这两个运算的结果是不同的。 (2认同)