python - 从离散信号计算FFT特征

标签 python fft sensor analysis

我有一个以10Hz采样的均匀信号数组(这意味着两个连续的数据点相隔100毫秒)。这实际上是3D陀螺仪3个轴的大小,该数组包含30个数据点(在3秒内)。
我将这个系列的频率绘制如下

import numpy as np
import matplotlib.pyplot as pl

sample_rate = 10
x = np.array([318.45,302.78,316.47,334.14,333.41,326.15,320.07,318.68,314.12,308.64,300.15,304.33,318.42,322.72,329.56,339.18,338.03,343.27,351.44,353.23,352.35,352.88,353.43,352.14,351.28,352.82,353.36,353.35,353.19,353.82])
x = np.array(x) - np.mean(x)
p = np.abs(np.fft.rfft(x))
f = np.linspace(0, sample_rate/2, len(p))
pl.plot(f, p)
pl.show()


有人可以告诉我我的计划正确吗?
我打算计算以下特征(根据上述信号)


直流分量
光谱能量
信息熵
主导频率分量
主频
FFT分析的前五个成分的大小


有人可以帮我填写上面的代码来计算这些功能吗?

---- @ RoadRunner66:由于无法回复您,所以请在下面查看我的问题----

谢谢您的回答和您的代码,

关于您的问题,数据来自测量欧拉角的陀螺仪示波器。

那么(sum x [i] ** 2:3357757.0)是光谱能量吗?如果是,那么是否需要通过将该数字除以n来对其进行归一化? (或与n相乘),但是以下两篇论文的定义有所不同。

就像在第一篇论文(下面的第一条链接)中一样,他们指出“第二个频域特征集被选择为频谱能量,它被定义为FFT系数平方的总和”

在第二篇文章(第二条链接)中,他们以另一种方式表示:“光谱能量:光谱系数的平方和除以一个窗口中的样本数”

那么“主频率”与“主导频率”具有相同的含义(术语)吗?我猜主频率是指唯一一个具有最高频谱峰值的频率?

我像这样将频率和等效幅度打印到两行中
enter image description here

我认为您像黄色的波纹管一样打印了前5个的大小。我不确定“前5个组件”的定义

如果我们像您所指出的那样使用前五个连续变量,将它们包括在内(如频率0或0.666)并将其输入我的预测模型(如下所述)是否有意义,因为与其他。如果返回频谱清晰可见,且主频率为1hz和3hz,则0.5hz或1.5hz频率处的幅度可能接近于零。

如我以蓝色突出显示的那样,术语“ FFT分析的前五个分量的幅度”是否是“前五个主要分量的幅度”?这个术语是指5个值还是1个值(5个平方和的平方根)?
如果它指的是5个值(很有可能是这样),那么在比较两个信号之间的差异时,我认为幅度最高的前5个主要成分将是一个更好的选择?

顺便说一句,第二篇论文还写道:“第一个5-FFT系数:快速傅里叶变换系数的前5个被采用,因为它们捕获了主要频率分量,而使用附加系数并没有提高精度”

坦率地说,我正在研究奶牛活动的问题,我的策略是将传感器数据分割为时间窗口(3、5、7..seconds)并从每个窗口中提取特征,然后将其输入到机器学习模型中。

(我的数据包括连接到母牛脖子的3d陀螺仪和3d加速度计,传感器数据采样率为10Hz)

我想结合两种类型的特征,一种是时域特征,另一种是频域特征。

我阅读了论文,发现了上述那些频域特征集,其中包括术语“ FFT分析的前五个成分的幅值”(摘自本文https://ieeexplore.ieee.org/abstract/document/4663615
从这个https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4634510/

他们将第二个称为“前5个FFT系数:采用快速傅里叶变换系数的前5个是因为它们捕获了主要频率分量,而使用其他系数并没有提高精度”。

非常感谢您的阅读和答复!

最佳答案

您已经完成了大部分工作。这似乎是针对班级作业的,因此可以解释数据的稀疏性,实际上并不需要太多。

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

sample_rate = 10 #Hz

x = np.array([318.45,302.78,316.47,334.14,333.41,326.15,320.07,318.68,314.12,308.64,
              300.15,304.33,318.42,322.72,329.56,339.18,338.03,343.27,351.44,353.23,
              352.35,352.88,353.43,352.14,351.28,352.82,353.36,353.35,353.19,353.82])
n=len(x)
print(f'number of points n : {n}')
t= np.linspace(0,3, n)     # time according to your description
mn=np.mean(x)
print(f' mean = {mn:.3f} unit')
print(f' sum x[i]**2  : {np.sum(x**2) :.1f} unit^2 ')

pr = np.abs(np.fft.rfft(x))/n
print()
print(f' DC peak :  {pr[0]};  this makes choice of normalization 1/n meaningful')

print(f' n *sum X[k]**2   : {np.sum(np.abs(pr)**2)*n :.1f} unit^2 ') 
f = np.linspace(0, sample_rate/2, len(pr))   # 10 Sa/sec, so 5 Hz is Nyquist limit

plt.figure(figsize=(20,5))

plt.subplot(141)
plt.plot(t,x,'.-')
plt.title('original data') 

plt.subplot(142)
plt.plot(f, pr,'.-')
plt.title('spectrum')


plt.subplot(143)
xf = np.array(x) - mn   #  remove the DC
plt.plot(t, xf,'.-')
plt.title('original data with DC removed')

plt.subplot(144)
pr = np.abs(np.fft.rfft(xf))/n
plt.plot(f, pr, '.-');
plt.title('spectrum (DC removed) ')


enter image description here

DC峰值与334个单位的原始信号的平均值相同。

频谱能量(请参见Parseval's Theorem)在时域和频域相同。

我不知道您期望使用哪种信息熵定义(例如,参见Approx. entropy)。

频谱中的主要频率(去掉DC后)分别为1/3 Hz,1 Hz和2 Hz,其中1/3 Hz最大。我打印了前五个的大小。

对我来说,一个重要的问题是数据的物理意义。他们是角度吗?如果是,以什么为单位?

请注意,人们可以分别以1/3 Hz(3秒内一波),1 Hz(1秒内一波)和2 Hz(1/2秒内一波)“看到”原始数据中的频率分量。 。

enter image description here

关于python - 从离散信号计算FFT特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59867883/

相关文章:

accelerometer - 如何确定绝对方向

Python keras 如何将密集层转换为卷积层

python - 对于列表中的索引

python - Accelerate 和 NumPy 为 FFT 产生不同的结果

C++ - 使用 AMD 源库的链接错误

python - 如何从 pandas 数据帧制作 PSD 图?

android - 如何以与Google Skymap相同的方式使用传感器值?

python - django 中的 DISTINCT ON

python - 使用 xlsxwriter 将 Excel 中单元格组的边框更改为粗框边框