指数衰减正弦函数的 FFT
FFT of exponentially decaying sinusoidal function
我有一组模拟数据,我想对其执行 FFT。我正在使用 matplotlib 来执行此操作。但是,FFT 看起来很奇怪,所以我不知道我的代码中是否遗漏了什么。非常感谢任何帮助。
原始数据:
time-varying data
傅里叶变换:
FFT
FFT 计算代码:
import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack as fftpack
data = pd.read_csv('table.txt',header=0,sep="\t")
fig, ax = plt.subplots()
mz_res=data[['mz ()']].to_numpy()
time=data[['# t (s)']].to_numpy()
ax.plot(time[:300],mz_res[:300])
ax.set_title("Time-varying mz component")
ax.set_xlabel('time')
ax.set_ylabel('mz amplitude')
fft_res=fftpack.fft(mz_res[:300])
power=np.abs(fft_res)
frequencies=fftpack.fftfreq(fft_res.size)
fig2, ax_fft=plt.subplots()
ax_fft.plot(frequencies[:150],power[:150]) // taking just half of the frequency range
我只是绘制了前 300 个数据点,因为其余的并不重要。
我是不是做错了什么?我期待的不是我得到的单频峰值。谢谢!
Link 输入文件:
编辑
原来错误出在将数据帧转换为 numpy 数组时。出于我尚未理解的原因,如果我将数据帧转换为 numpy 数组,它将转换为数组数组,即结果数组的每个元素本身就是单个元素的数组。当我将代码更改为:
mz_res=data['mz ()'].to_numpy()
所以它是从 pandas 系列 到 numpy 数组的转换,然后 FFT 的行为符合预期,我从 FFT 得到单频峰值。
所以我只是把它放在这里以防其他人发现它有用。经验教训:从 pandas 系列到 numpy 数组的转换产生的结果与从 pandas 数据帧的转换产生的结果不同。
解决方案:
使用从 pandas 系列到 numpy 数组的转换而不是 pandas 数据帧到 numpy 数组的转换。
代码:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack as fftpack
data = pd.read_csv('table.txt',header=0,sep="\t")
fig, ax = plt.subplots()
mz_res=data['mz ()'].to_numpy() #series to array
time=data[['# t (s)']].to_numpy() #dataframe to array
ax.plot(time,mz_res)
ax.set_title("Time-varying mz component")
ax.set_xlabel('time')
ax.set_ylabel('mz amplitude')
fft_res=fftpack.fft(mz_res)
power=np.abs(fft_res)
frequencies=fftpack.fftfreq(fft_res.size)
indices=np.where(frequencies>0)
freq_pos=frequencies[indices]
power_pos=power[indices]
fig2, ax_fft=plt.subplots()
ax_fft.plot(freq_pos,power_pos) # taking just half of the frequency range
ax_fft.set_title("FFT")
ax_fft.set_xlabel('Frequency (Hz)')
ax_fft.set_ylabel('FFT Amplitude')
ax_fft.set_yscale('linear')
产量:
Time-dependence
FFT
我有一组模拟数据,我想对其执行 FFT。我正在使用 matplotlib 来执行此操作。但是,FFT 看起来很奇怪,所以我不知道我的代码中是否遗漏了什么。非常感谢任何帮助。
原始数据:
time-varying data
傅里叶变换:
FFT
FFT 计算代码:
import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack as fftpack
data = pd.read_csv('table.txt',header=0,sep="\t")
fig, ax = plt.subplots()
mz_res=data[['mz ()']].to_numpy()
time=data[['# t (s)']].to_numpy()
ax.plot(time[:300],mz_res[:300])
ax.set_title("Time-varying mz component")
ax.set_xlabel('time')
ax.set_ylabel('mz amplitude')
fft_res=fftpack.fft(mz_res[:300])
power=np.abs(fft_res)
frequencies=fftpack.fftfreq(fft_res.size)
fig2, ax_fft=plt.subplots()
ax_fft.plot(frequencies[:150],power[:150]) // taking just half of the frequency range
我只是绘制了前 300 个数据点,因为其余的并不重要。
我是不是做错了什么?我期待的不是我得到的单频峰值。谢谢!
Link 输入文件:
编辑
原来错误出在将数据帧转换为 numpy 数组时。出于我尚未理解的原因,如果我将数据帧转换为 numpy 数组,它将转换为数组数组,即结果数组的每个元素本身就是单个元素的数组。当我将代码更改为:
mz_res=data['mz ()'].to_numpy()
所以它是从 pandas 系列 到 numpy 数组的转换,然后 FFT 的行为符合预期,我从 FFT 得到单频峰值。
所以我只是把它放在这里以防其他人发现它有用。经验教训:从 pandas 系列到 numpy 数组的转换产生的结果与从 pandas 数据帧的转换产生的结果不同。
解决方案:
使用从 pandas 系列到 numpy 数组的转换而不是 pandas 数据帧到 numpy 数组的转换。
代码:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack as fftpack
data = pd.read_csv('table.txt',header=0,sep="\t")
fig, ax = plt.subplots()
mz_res=data['mz ()'].to_numpy() #series to array
time=data[['# t (s)']].to_numpy() #dataframe to array
ax.plot(time,mz_res)
ax.set_title("Time-varying mz component")
ax.set_xlabel('time')
ax.set_ylabel('mz amplitude')
fft_res=fftpack.fft(mz_res)
power=np.abs(fft_res)
frequencies=fftpack.fftfreq(fft_res.size)
indices=np.where(frequencies>0)
freq_pos=frequencies[indices]
power_pos=power[indices]
fig2, ax_fft=plt.subplots()
ax_fft.plot(freq_pos,power_pos) # taking just half of the frequency range
ax_fft.set_title("FFT")
ax_fft.set_xlabel('Frequency (Hz)')
ax_fft.set_ylabel('FFT Amplitude')
ax_fft.set_yscale('linear')
产量:
Time-dependence
FFT