如何找到跨越微时间单位的时间序列的周期性?

时间:2018-11-30 04:40:20

标签: python pandas statsmodels

我有一个时间序列,其中时间单位为毫秒 大约有3000个条目。我正在尝试找出季节性 该系列的数据,例如,检测数据中的任何周期性故障。数据是 表示为熊猫数据框。

我尝试使用statsmodel中的seasonal_decompose()方法,如下所示:

import pandas as pd
data = pd.read_csv('Sample_data.csv',index_col=0)
data.index = pd.to_datetime(data.index)
print(data.head())
##                              Sample_values
## Dates    
## 1970-01-01 05:30:00.000000   0.466812
## 1970-01-01 05:30:00.016667   0.218692
## 1970-01-01 05:30:00.033333   0.938067
## 1970-01-01 05:30:00.050000   0.480025
## 1970-01-01 05:30:00.066667   0.915175
print(type(data))
##  <class 'pandas.core.frame.DataFrame'>
from statsmodels.tsa.seasonal import seasonal_decompose
result = seasonal_decompose(data, model='additive')
fig = result.plot()

但是会导致以下错误:

ValueError: You must specify a freq or x must be a pandas object with a timeseries index with a freq not set to None

但是,如果我对x轴单位为月的数据集使用相同的代码(例如,从https://www.analyticsvidhya.com/wp-content/uploads/2016/02/AirPassengers.csv下载),则不会出现任何错误,并且我从Season_decompose()获得了4个图预期的。

那么我该如何检测我的数据的季节性模式,这种模式仅跨越 几个小时?

1 个答案:

答案 0 :(得分:0)

您需要为日期时间索引定义freq

使用以下内容:

                            sample_values
1970-01-01 05:30:00.000000       0.466812
1970-01-01 05:30:00.016667       0.218692
1970-01-01 05:30:00.033333       0.938067
1970-01-01 05:30:00.050000       0.480025
1970-01-01 05:30:00.066667       0.915175

当前频率为None

In [1]: print df.index
DatetimeIndex([       '1970-01-01 05:30:00', '1970-01-01 05:30:00.016667',
               '1970-01-01 05:30:00.033333', '1970-01-01 05:30:00.050000',
               '1970-01-01 05:30:00.066667'],
              dtype='datetime64[ns]', freq=None)

熊猫infer_freq函数无法检测到它:

In [2]: print pd.infer_freq(df.index)
None

如果知道数据的频率,则可以重新索引到该频率。但是,这对于您的索引来说很困难,因为时间戳中的重复小数点需要四舍五入到某个定义的时间间隔。这很接近:

In [3]: df_freq = df.resample('.000001S').ffill().reindex(pd.date_range(df.index[0],df.index[-1],freq='0.016667S'))

In [4]: print df_freq
                            sample_values
1970-01-01 05:30:00.000000       0.466812
1970-01-01 05:30:00.016667       0.218692
1970-01-01 05:30:00.033334       0.938067
1970-01-01 05:30:00.050001       0.480025

In [5]: print df_freq.index
DatetimeIndex([       '1970-01-01 05:30:00', '1970-01-01 05:30:00.016667',
               '1970-01-01 05:30:00.033334', '1970-01-01 05:30:00.050001'],
              dtype='datetime64[ns]', freq='16667U')

现在您已经定义了freq。在完整的数据集上尝试一下,看看seasonal_decompose()是否将运行。但是,在很长一段时间内,时间戳可能会变得不准确。

您还可以尝试以下操作:

In [6]: df_freq = df.resample('.000001S').interpolate().resample('.005S').first()

In [7]: print df_freq
                         sample_values
1970-01-01 05:30:00.000       0.466812
1970-01-01 05:30:00.005       0.392377
1970-01-01 05:30:00.010       0.317943
1970-01-01 05:30:00.015       0.243508
1970-01-01 05:30:00.020       0.362558
1970-01-01 05:30:00.025       0.578380
1970-01-01 05:30:00.030       0.794201
1970-01-01 05:30:00.035       0.892255
1970-01-01 05:30:00.040       0.754845
1970-01-01 05:30:00.045       0.617435
1970-01-01 05:30:00.050       0.480025
1970-01-01 05:30:00.055       0.610567
1970-01-01 05:30:00.060       0.741110
1970-01-01 05:30:00.065       0.871652

具有freq='5L',并使用线性插值法以规则的频率索引来近似原始数据的趋势。您可以使用.005S来测试第二个下采样频率,以根据需要获得更高或更低的频率。