Python中的时间序列分析,使用傅里叶(或其他方法)

1 投票
2 回答
3860 浏览
提问于 2025-04-18 02:05

寻找时间戳序列中的重复和周期

我有一些时间戳数据(大约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 个回答

1

假设你的分辨率是一分钟,你可以用声谱图快速查看一些模式:

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()(这是一种功率谱密度)。请注意,只有当你有足够多的时间戳时,才能得到好看的图像。

2

你可以把时间戳数据转换成时间序列,时间序列的精度和时间戳数据的精度是一样的。

你的时间戳例子显示的是一分钟的精度。对于这种数据,你的时间序列也会是一分钟的精度。

你可以创建一个数组,在你没有时间戳数据的地方填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计算。

这个图表示上面的时间戳数组:

时间戳数据时间序列 - Sooeet.com FFT计算器

这个图显示了上面时间戳数组的频率谱(FFT)。最大的峰值位于0.002赫兹(每秒周期数),这是输入数据的基本频率。换句话说,时间序列的基本周期是1/0.002=480秒,也就是8分钟。

时间戳数据的频率谱 - Sooeet.com FFT计算器

频率谱显示了两个较小的峰值,分别在f=0.004赫兹和f=0.0065赫兹。

你想要的信息更适合用统计分析来处理。傅里叶分析无法提供这些数据的详细信息。

图表和FFT是用Sooeet FFT计算器完成的。

撰写回答