【发布时间】:2020-12-17 06:46:32
【问题描述】:
我正在努力从给定的数据集中查找频率,我正在努力理解 np.fft.fft() 的工作原理。我以为我有一个工作脚本,但遇到了一个我无法理解的奇怪问题。
我有一个大致为正弦曲线的数据集,我想了解信号由哪些频率组成。一旦我进行了 FFT,我就得到了这个情节:
但是,当我采用相同的数据集,将其切成两半并绘制相同的东西时,我得到了:
我不明白为什么频率从 144kHz 下降到 128kHz,这在技术上应该是相同的数据集,但长度更小。
我可以确认几件事:
- 数据点之间的步长 0.001
- 我尝试过插值,但运气不佳。
- 如果我对数据集的后半部分进行切片,我也会得到不同的频率。
- 如果我的数据集确实由 128 和 144kHz 组成,那么为什么第一个图中没有出现 128 峰值?
更令人困惑的是,我正在运行一个没有问题的纯正弦波脚本:
T = 0.001
fs = 1 / T
def find_nearest_ind(data, value):
return (np.abs(data - value)).argmin()
x = np.arange(0, 30, T)
ff = 0.2
y = np.sin(2 * ff * np.pi * x)
x = x[:len(x) // 2]
y = y[:len(y) // 2]
n = len(y) # length of the signal
k = np.arange(n)
T = n / fs
frq = k / T * 1e6 / 1000 # two sides frequency range
frq = frq[:len(frq) // 2] # one side frequency range
Y = np.fft.fft(y) / n # dft and normalization
Y = Y[:n // 2]
frq = frq[:50]
Y = Y[:50]
fig, (ax1, ax2) = plt.subplots(2)
ax1.plot(x, y)
ax1.set_xlabel("Time (us)")
ax1.set_ylabel("Electric Field (V / mm)")
peak_ind = find_nearest_ind(abs(Y), np.max(abs(Y)))
ax2.plot(frq, abs(Y))
ax2.axvline(frq[peak_ind], color = 'black', linestyle = '--', label = F"Frequency = {round(frq[peak_ind], 3)}kHz")
plt.legend()
plt.xlabel('Freq(kHz)')
ax1.title.set_text('dV/dX vs. Time')
ax2.title.set_text('Frequencies')
fig.tight_layout()
plt.show()
【问题讨论】:
-
所有情况下的最大频率都应该相同:如果您以 1kHz 采样,那么无论您有多少采样,您的奈奎斯特频率都是 500Hz。所以从那里开始
-
频轴:
np.linspace(0, 1, N) / T -
find_nearest_ind(abs(Y), np.max(abs(Y)))只是np.abs(Y).argmax()。你根本不需要这个函数。 -
您的周期在图中是 6-7 微秒。很明显,频率应该在 140 到 160 kHz 之间
-
为了这个问题的目的,删除带有真实数据集的部分。您的问题应该始终关注单个独立的 MCVE,而不是您的真实代码。
标签: python numpy fft frequency-analysis