web-dev-qa-db-ja.com

Pythonで時系列のローリング/移動分散を簡単に計算するにはどうすればよいですか?

単純な時系列があり、変動するウィンドウ内の分散を推定するのに苦労しています。具体的には、スライディングウィンドウ関数の実装方法に関するいくつかの問題を理解できません。たとえば、NumPyとウィンドウサイズ= 20を使用する場合:

def rolling_window(a, window):
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    strides = a.strides + (a.strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides) 

rolling_window(data, 20)
np.var(rolling_window(data, 20), -1)
datavar=np.var(rolling_window(data, 20), -1)

おそらく、私はこの考えのどこかで間違っています。誰かがこれを行う簡単な方法を知っていますか?どんなヘルプ/アドバイスでも大歓迎です。

14
Barry

pandas を見てください。例えば:

import pandas as pd
import numpy as np

# some sample data
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000)).cumsum()

#plot the time series
ts.plot(style='k--')

# calculate a 60 day rolling mean and plot
pd.rolling_mean(ts, 60).plot(style='k')

# add the 20 day rolling variance:
pd.rolling_std(ts, 20).plot(style='b')

enter image description here

14
elyase

Pandas rolling_meanおよびrolling_std関数は廃止され、より一般的な「ローリング」フレームワークに置き換えられました。 @elyaseの例は次のように変更できます。

import pandas as pd
import numpy as np
%matplotlib inline

# some sample data
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000)).cumsum()

#plot the time series
ts.plot(style='k--')

# calculate a 60 day rolling mean and plot
ts.rolling(window=60).mean().plot(style='k')

# add the 20 day rolling standard deviation:
ts.rolling(window=20).std().plot(style='b')

rolling関数は、 here で説明されているように、さまざまなウィンドウタイプをサポートしています。 rollingおよびその他の興味深い統計情報(varskewkurtなど)を含む、quantileオブジェクトでいくつかの関数を呼び出すことができます。プロットが平均と同じグラフ上にあるので、stdを使用しています。

16
sfjac

古いスレッドであるにも関わらず、私は this から変更された別のメソッドを追加します。これは、パンダにもpythonループにも依存しません。基本的に、numpyのストライドトリックを使用します。最初にストライドで配列のビューを作成し、最後の軸に沿って関数の統計を計算することはローリング統計を実行することと同じになるようにします。出力形状が入力形状と同じになるように元のコードを変更しましたパディングにより、最後の軸の始まりを追加します。

import numpy as np

def rolling_window(a, window):
    pad = np.ones(len(a.shape), dtype=np.int32)
    pad[-1] = window-1
    pad = list(Zip(pad, np.zeros(len(a.shape), dtype=np.int32)))
    a = np.pad(a, pad,mode='reflect')
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    strides = a.strides + (a.strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)

a = np.arange(30).reshape((5,6))

# rolling mean along last axis
np.mean(rolling_window(a, 3), axis=-1)

# rolling var along last axis
np.var(rolling_window(a, 3), axis=-1)

# rolling median along last axis
np.median(rolling_window(a, 3), axis=-1)

1
Josh Albert