Python 使用快速傅里叶变换获得正确的频率

Python 使用快速傅里叶变换获得正确的频率,python,numpy,fft,frequency-analysis,Python,Numpy,Fft,Frequency Analysis,我试图了解数据集的频率,但在快速傅立叶变换的工作中遇到了问题。主要的问题是我不知道如何在x轴上获得正确的频率 背景 我有一个包含许多列的数据集,但感兴趣的列是TOF(飞行时间)和dE/dx。我已附加包含数据的CSV文件。下面是我访问它的方式 import pandas as pd file = 'np_15us.csv' dataset = pd.read_csv(file,skiprows=8) df = dataset[:-1] #necesssary because last row of

我试图了解数据集的频率,但在快速傅立叶变换的工作中遇到了问题。主要的问题是我不知道如何在x轴上获得正确的频率

背景

我有一个包含许多列的数据集,但感兴趣的列是TOF(飞行时间)和dE/dx。我已附加包含数据的CSV文件。下面是我访问它的方式

import pandas as pd
file = 'np_15us.csv'
dataset = pd.read_csv(file,skiprows=8)
df = dataset[:-1] #necesssary because last row of the dataset is null for some reason
x = df['TOF'] #TOF is in micro-seconds
y= df['dE/dx']
现在,当你绘制
x vs.y
时,它大致是一个正弦曲线。我可以看到频率大概是116kHz。我希望通过使用快速傅里叶变换得到准确的频率,因为我希望其他数据集是不完美的正弦曲线

问题

当我尝试使用此代码获取数据集的
fft
时:

import numpy as np
x_new = np.arange(0,14, dt)
y_new = func_1(x_new)
fs = len(y_new)

fig = plt.figure(2)
plt.subplot(2,1,1)
plt.plot(x_new, y_new)
plt.xlabel('time (usec)')
plt.ylabel('E (V/mm)')
plt.subplot(2,1,2)
fft = np.fft.fft(y)/len(y)
fft = fft[range(int(len(y)/2))]
tpCount = len(fft)
values = np.arange(int(tpCount))
timePeriod = tpCount/samp
frequencies = (values/(2*timePeriod))*10**6 #followed some tutorial to get here
plt.plot(frequencies[:100], abs(fft)[:100]) #zooming in to one of the peaks 
fig.tight_layout()
plt.show()
我知道

这个频率大约为260kHz,这是一个高估值。我可以使用
np.fft.fftfreq
运行相同的脚本来获取

func_1 = interpolate.interp1d(x, y)
samp = 100
dt = 1/samp
x_new = np.arange(0,14, dt)
y_new = func_1(x_new)
fs = len(y_new)
fig = plt.figure(2)
plt.subplot(2,1,1)
plt.plot(x_new, y_new)
plt.xlabel('time (usec)')
plt.ylabel('E (V/mm)')
plt.subplot(2,1,2)
fft = np.fft.fft(y)/len(y)
freqs = np.fft.fftfreq(len(fft),dt)
fft_shift = np.fft.fftshift(fft)
freqs = np.fft.fftshift(freqs)
plt.plot(freqs[int(len(freqs)/2):int(len(freqs))-300], abs(fft_shift[int(len(fft_shift)/2):int(len(freqs))-300]) #now I don't understand the frequnecies
fig.tight_layout()
plt.show()

无论我用哪种方式,我都会得到错误的频率。所以,我肯定是做错了什么。我真的不明白如何使用np.fft.fftfreq计算频率

我不知道数据集的采样频率,这就是为什么我要插值以获得更多的控制权。我不确定我是否应该这样做。我想使用
np.fft.fftfreq
,因为它的代码看起来更干净

谢谢你的帮助。如果你有任何问题,请告诉我

请注意-在这种情况下,数据集中的dE/dx实际上应该是dV/dx,如第一个图所示。刚才的CSV文件命名不正确


链接到CSV文件-

如果您的数据非常接近这样的正弦曲线,并且您通常至少有一个周期,我认为您将在时域中得到更好的估计。FFT在垃圾箱中有能量,它只是选择最上面的垃圾箱不会给你最好的结果

我将测量dE/dx值的零交叉点之间的距离。(进行线性插值以获得更精确的过零位置)。甚至不做插值,我得到了117.9kHz的值