使用 numpy 的傅立叶变换找到时间序列的最可能周期性?
Posted
技术标签:
【中文标题】使用 numpy 的傅立叶变换找到时间序列的最可能周期性?【英文标题】:Find likeliest periodicity for time series with numpy's Fourier Transform? 【发布时间】:2017-12-01 20:40:55 【问题描述】:假设我有一个包含一百个测量值的时间序列 t,每个条目代表每天的测量值。我假设信号中存在一定的周期性——它可能每天、每周或每月重复一次。
将时间序列转换为傅里叶域可能有助于找到这样的周期性?
如何使用 numpy 的 fft 模块为我的时间序列找到最可能的时期?
【问题讨论】:
对数据做FFT,看看哪个周期的幅度最大。 你的意思是FFT的数组索引与最大条目(幅度)是周期? 是对您的数据影响最大的周期性。原则上,任何只有等于 0 的幅度都是没有贡献的周期性。 不明白fft和fftfreq函数有什么关系? 如果你想找到一年的时间段(尤其是最小/最大的位置),你需要一个足够长的数据系列。 【参考方案1】:我的目标是回答我自己的问题。你可以在适当的地方纠正我。
假设我们的时间序列 t 是 t = [2,1,0,1,2,3,2,1,0,1,2,3,2,1,0,1,2,3]
,有 18 个测量值。一个相当简单的例子:周期的长度似乎很可能是六个时间单位。
将这个时间序列带入频域得到我们:
w = numpy.fft.fft(t)
print numpy.absolute(w)
array([27.000000, 0.000000, 0.000000, 12.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 3.000000, 0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 12.000000, 0.000000, 0.000000])
我们忽略频率 0 并观察到索引 3 的值最大 - 这表明在我们的时间序列 t 内信号重复 3 次。因此,信号的长度——周期——将是 18/3 = 6。事实上:
numpy.fft.fftfreq(18)
array([ 0. , 0.055556, 0.111111, 0.166667, 0.222222, 0.277778,
0.333333, 0.388889, 0.444444, -0.5 , -0.444444, -0.388889,
-0.333333, -0.277778, -0.222222, -0.166667, -0.111111, -0.055556])
索引 3 处的频率正好是 1/6,即一个时间单位的频率是 1/6,这意味着信号在整个周期内需要六个时间单位。
如果我的理解正确,请告诉我。
【讨论】:
你确定你的解释最后是否正确?【参考方案2】:请注意,FFT 会发现正弦分解,这与周期性估计器不同(因为任何基本周期都可能完全从周期性信号的频谱中丢失。请参阅 missing fundamental)
因此,您需要使用倒谱(使用复杂的倒谱分析等)对 FFT 结果进行后处理,或者可能使用谐波乘积谱估计器。
【讨论】:
【参考方案3】:还有另一种不依赖傅立叶级数的方法。这个方法可以帮助你 识别信号是否是周期性的。理想情况下,在这种情况下,时间序列应该是二进制的:
[0,1,0,0,0,1,1,0,0,0,1,0,0,1]
您首先计算连续峰值位置之间的距离分布。然后,你计算因子
-1<B<1:
B = (var - mean)/(var + mean)
mean
和 varrespectively the mean and the variance of the computed distribution. The closer
Bto
-1the more periodic the signal is. If
B` 接近 0,则信号中没有周期性,峰值在时间序列中随机分布。
有关更多信息,请查找关键字 Burstiness。
【讨论】:
这个理论有参考吗?寻找简单的突发性并没有多大帮助minimal reproducible example (en.wikipedia.org/wiki/Burstiness)。提前致谢。 是的,这里是链接iopscience.iop.org/article/10.1209/0295-5075/81/48002/pdf 图1是一个很好的插图以上是关于使用 numpy 的傅立叶变换找到时间序列的最可能周期性?的主要内容,如果未能解决你的问题,请参考以下文章