Python中的时间序列分析,使用傅里叶(或其他方法)
寻找时间戳序列中的重复和周期
我有一些时间戳数据(大约5000到50000个时间戳),这些数据在一个月或几个月内分布不均:
example1 = ['2013-01-01 12:01', '2013-01-01 12:26', '2013-01-01 12:58']
输入可以是像上面那样的列表,或者我可以把它放进numpy数组中,也许强制让时间戳在分钟上均匀分布:
exempel2 = np.array(['2013-01-01 12:01', '2013-01-01 12:02', '2013-01-01 12:03'])
dummyArr = np.array([1, 0, 0])
...然后再有一个形状相同的数组,用来标记另一个数组中相同位置的时间戳(例子2)是否是需要考虑的日期/时间(1表示考虑,0表示不考虑)
我的问题是,傅里叶变换是否是用Python实现来寻找时间戳序列中模式(重复、周期)的最佳选择,如果是傅里叶变换,最好的做法是什么?
正如我所说,我在寻找重复和周期。每小时的分辨率听起来不错,但我有点不确定。我只是想知道,比如说每天中午11点到13点之间有一个模式。每第七天大约在17点又有一个模式。也许还有一个复杂的模式,随着一年时间的推移而增长,先是7天,然后是8天,再然后是9天,都是在这些时间戳中得出的,结果中可能还会有一些标记,表示这个模式的强度或弱度。
2 个回答
假设你的分辨率是一分钟,你可以用声谱图快速查看一些模式:
import time
import numpy as np
import matplotlib.pyplot as plt
# convert time stamps to seconds (of UNIX time):
tt_sec = np.array([int(time.mktime(time.strptime(e,"%Y-%m-%d %H:%M"))) for e in example1])
tt = (tt_sec - tt_sec[0]) / 60 # convert to minutes starting at 0
xx = np.zeros(max(tt) + 1) # make sampled array with peaks at time stamps
xx[tt] = 1
# make spectrogram:
fg = plt.figure(1)
fg.clf()
ax = fg.add_subplot(1, 1, 1)
ax.specgram(xx, Fs=1./60) # spectogram => tune the parameters
fg.canvas.draw() # do the drawing
plt.show() # enter interactive loop
看看matplotlib的specgram()
的说明文档,试着调整一下参数。如果你懒得使用np.fft.rfft()
,可以试试plt.psd()
(这是一种功率谱密度)。请注意,只有当你有足够多的时间戳时,才能得到好看的图像。
你可以把时间戳数据转换成时间序列,时间序列的精度和时间戳数据的精度是一样的。
你的时间戳例子显示的是一分钟的精度。对于这种数据,你的时间序列也会是一分钟的精度。
你可以创建一个数组,在你没有时间戳数据的地方填0(零),在有时间戳数据的地方填1(一个)。
这样你就得到了一个用于FFT(快速傅里叶变换)的输入数据数组,类似于从随机时间戳数据构建的这个数组:
[0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0]
要找到你的时间戳数据的频率谱,可以对这个数组进行FFT计算。
这个图表示上面的时间戳数组:
这个图显示了上面时间戳数组的频率谱(FFT)。最大的峰值位于0.002赫兹(每秒周期数),这是输入数据的基本频率。换句话说,时间序列的基本周期是1/0.002=480秒,也就是8分钟。
频率谱显示了两个较小的峰值,分别在f=0.004赫兹和f=0.0065赫兹。
你想要的信息更适合用统计分析来处理。傅里叶分析无法提供这些数据的详细信息。
图表和FFT是用Sooeet FFT计算器完成的。