python - 现有数据帧上的快速傅立叶变换显示出意想不到的结果
问题描述
我有一个包含电压数据的文件,当我随时间绘制数据时,我可以看到它是一个带频率.csv
的正弦波。60hz
现在,当我尝试fft
使用这些scipy/numpy fft
模块执行时,我在接近0
频率处得到一个尖峰,而从逻辑上讲它应该在60
. (如下图)
当我用在 python 中创建的正弦波尝试它时,我得到了正确的结果,但我没有用我的实际数据得到它。
我在下面分享我的代码,如果我做错了什么,请告诉我。提前致谢。
import csv
from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
from scipy.fftpack import fft
from scipy.fftpack import fftfreq
df = pd.read_csv('Va_data.csv')
print(df.head())
N = df.shape[0]
frequency = np.linspace(0.0,100, int(N/2))
freq_data = fft(df['Va'])
y = (2/N)*np.abs(freq_data[0:np.int(N/2)])
plt.plot(frequency, y)
plt.title('Frequency Domain Signal')
plt.xlabel('Frequency in Hz')
plt.ylabel('Amplitude')
plt.show()
解决方案
数据应该很好,FFT 计算(直到一个常数)也很好。它是关于如何绘制结果的。要使 x 轴值以赫兹表示频率信息,您需要
frequency = np.arange(N) / N * sampling_rate
然后你可以裁剪它的一半
frequency = frequency[:N//2]
并将其交给plt.plot(frequency, y)
. 上面的方程frequency
来自这样一个事实,即每个 DFT 系数X(k)
都有k = 0, .., N-1
一个exp(-j 2pi kn/N)
,其中k/N
给出了归一化频率。乘以采样率可以恢复对应于连续域的频率。
一个样品:
# sample x data
xs = np.linspace(0, 4, 1_000)
# sampling rate in this case
fs = 1 / np.diff(xs)[0]
# sine of it
ys = np.sin(2 * np.pi * 60 * xs)
# taking FFT
dft = np.fft.fft(ys)
# getting x-axis values to represent freq in Hz
N = len(xs)
x_as_freq = np.arange(N) / N * fs
# now plotting it
plt.plot(x_as_freq, np.abs(dft))
plt.xlabel("Frequency (Hz)")
plt.ylabel("DFT magnitude")
# to see that peak is indeed at 60Hz
plt.xticks(np.arange(0, 250, 20))
这使
推荐阅读
- gradle - 如何在 gradle plugins 块中使用环境变量?
- php - Coinbase API PHP 获取当前资产 - 嵌套对象数组
- sql - 替换选择中的值
- node.js - 读取 kafka 主题并通过 Rest API 公开数据以供 prometheus 抓取(Nodejs)
- cytoscape.js - 当用户拖动并释放节点时,如何在 cytoscape 中捕获数据的位置?
- json - 为什么 rapidjson 有错误并且说 json 文件是 NULL 而它有数据?
- python - 我如何为熊猫结合 np.where 和 fillna
- c++ - 无法创建具有给定数量元素的链表
- html - 浮动按钮显示在网页下方
- powershell - Powershell 从安排好的报告中获取内容