web-dev-qa-db-ja.com

時系列分析-不等間隔のメジャー-pandas + statsmodels

Numpy配列のlight_pointsとtime_pointsが2つあり、これらのデータに対して時系列分析手法をいくつか使用したいと考えています。

私はこれを試しました:

import statsmodels.api as sm
import pandas as pd
tdf = pd.DataFrame({'time':time_points[:]})
rdf =  pd.DataFrame({'light':light_points[:]})
rdf.index = pd.DatetimeIndex(freq='w',start=0,periods=len(rdf.light))
#rdf.index = pd.DatetimeIndex(tdf['time'])

これは機能しますが、正しいことを行っていません。実際、測定値は等間隔ではなく、time_points pandas DataFrameをフレームのインデックスとして宣言した場合、エラーが発生します。

rdf.index = pd.DatetimeIndex(tdf['time'])

decomp = sm.tsa.seasonal_decompose(rdf)

Elif freq is None:
raise ValueError("You must specify a freq or x must be a pandas object with a timeseries index")

ValueError: You must specify a freq or x must be a pandas object with a timeseries index

これを修正する方法がわかりません。また、パンダのTimeSeriesは廃止されているようです。

私はこれを試しました:

rdf = pd.Series({'light':light_points[:]})
rdf.index = pd.DatetimeIndex(tdf['time'])

しかし、それは私に長さの不一致を与えます:

ValueError: Length mismatch: Expected axis has 1 elements, new values have 122 elements

それでも、rdf ['light']とtdf ['time']は同じ長さなので、どこから来たのかわかりません...

結局、私は自分のrdfをpandas Seriesとして定義してみました:

rdf = pd.Series(light_points[:],index=pd.DatetimeIndex(time_points[:]))

そして私はこれを手に入れます:

ValueError: You must specify a freq or x must be a pandas object with a timeseries index

次に、代わりにインデックスを置き換えてみました

 pd.TimeSeries(time_points[:])

そして、seasonal_decomposeメソッド行でエラーが発生します。

AttributeError: 'Float64Index' object has no attribute 'inferred_freq'

不等間隔のデータを処理するにはどうすればよいですか?既存の値の間に多くの不明な値を追加し、補間を使用してそれらのポイントを「評価」することで、ほぼ等間隔の時間配列を作成することを考えていましたが、よりクリーンで簡単な解決策があると思います。

13
Robin

seasonal_decompose()にはfreqが必要です。これはDateTimeIndexメタ情報の一部として提供されるか、_pandas.Index.inferred_freq_から、またはユーザーがintegerは、サイクルごとの期間数を示します。例:毎月12(docstring for _seasonal_mean_から):

_def seasonal_decompose(x, model="additive", filt=None, freq=None):
    """
    Parameters
    ----------
    x : array-like
        Time series
    model : str {"additive", "multiplicative"}
        Type of seasonal component. Abbreviations are accepted.
    filt : array-like
        The filter coefficients for filtering out the seasonal component.
        The default is a symmetric moving average.
    freq : int, optional
        Frequency of the series. Must be used if x is not a pandas
        object with a timeseries index.
_

説明するには-ランダムなサンプルデータを使用します。

_length = 400
x = np.sin(np.arange(length)) * 10 + np.random.randn(length)
df = pd.DataFrame(data=x, index=pd.date_range(start=datetime(2015, 1, 1), periods=length, freq='w'), columns=['value'])

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 400 entries, 2015-01-04 to 2022-08-28
Freq: W-Sun

decomp = sm.tsa.seasonal_decompose(df)
data = pd.concat([df, decomp.trend, decomp.seasonal, decomp.resid], axis=1)
data.columns = ['series', 'trend', 'seasonal', 'resid']

Data columns (total 4 columns):
series      400 non-null float64
trend       348 non-null float64
seasonal    400 non-null float64
resid       348 non-null float64
dtypes: float64(4)
memory usage: 15.6 KB
_

これまでのところ、とても良いです。DateTimeIndexから要素をランダムに削除して、不均一なスペースデータを作成します。

_df = df.iloc[np.unique(np.random.randint(low=0, high=length, size=length * .8))]

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 222 entries, 2015-01-11 to 2022-08-21
Data columns (total 1 columns):
value    222 non-null float64
dtypes: float64(1)
memory usage: 3.5 KB

df.index.freq

None

df.index.inferred_freq

None
_

このデータで_seasonal_decomp_を実行すると「機能する」:

_decomp = sm.tsa.seasonal_decompose(df, freq=52)

data = pd.concat([df, decomp.trend, decomp.seasonal, decomp.resid], axis=1)
data.columns = ['series', 'trend', 'seasonal', 'resid']

DatetimeIndex: 224 entries, 2015-01-04 to 2022-08-07
Data columns (total 4 columns):
series      224 non-null float64
trend       172 non-null float64
seasonal    224 non-null float64
resid       172 non-null float64
dtypes: float64(4)
memory usage: 8.8 KB
_

問題は、結果がどれほど役立つかです。季節パターンの推論を複雑にするデータのギャップがなくても( リリースノート.interpolate()の使用例を参照)、statsmodelsは、このプロシージャを次のように修飾します。

_Notes
-----
This is a naive decomposition. More sophisticated methods should
be preferred.

The additive model is Y[t] = T[t] + S[t] + e[t]

The multiplicative model is Y[t] = T[t] * S[t] * e[t]

The seasonal component is first removed by applying a convolution
filter to the data. The average of this smoothed series for each
period is the returned seasonal component.
_
13
Stefan