web-dev-qa-db-ja.com

Pandas Rolling Applyカスタム

私は同様の答え here を追ってきましたが、sklearnを使用してローリングアプライを行うときにいくつか質問があります。 Zスコアを作成してローリングアプライでPCAを実行しようとしていますが、引き続き'only length-1 arrays can be converted to Python scalars' error.

前の例に従って、データフレームを作成します

from sklearn.preprocessing import StandardScaler
import pandas as pd
import numpy as np
sc=StandardScaler() 
tmp=pd.DataFrame(np.random.randn(2000,2)/10000,index=pd.date_range('2001-01-01',periods=2000),columns=['A','B'])

rollingコマンドを使用する場合:

 tmp.rolling(window=5,center=False).apply(lambda x: sc.fit_transform(x))
 TypeError: only length-1 arrays can be converted to Python scalars

このエラーが発生します。ただし、平均および標準偏差のある関数を問題なく作成できます。

def test(df):
    return np.mean(df)
tmp.rolling(window=5,center=False).apply(lambda x: test(x))

Zスコアの現在の値から平均値を減算しようとするとエラーが発生すると思います。

def test2(df):
    return df-np.mean(df)
tmp.rolling(window=5,center=False).apply(lambda x: test2(x))
only length-1 arrays can be converted to Python scalars

最初に標準化してからPCAを実行するために、sklearnでカスタムローリング関数を作成するにはどうすればよいですか?

編集:私は私の質問が正確に明確ではなかったことに気づいたので、もう一度試してみます。値を標準化してからPCAを実行し、各要因によって説明される分散の量を取得します。ローリングせずにこれを行うことはかなり簡単です。

testing=sc.fit_transform(tmp)
pca=decomposition.pca.PCA() #run pca
pca.fit(testing) 
pca.explained_variance_ratio_
array([ 0.50967441,  0.49032559])

転がるときにこの同じ手順を使用することはできません。 @piRSquaredのローリングzscore関数を使用すると、zscoreが得られます。 sklearnのPCAは、ローリングアプライカスタム機能と互換性がないようです。 (実際、これはほとんどのsklearnモジュールの場合だと思います。)1次元の項目である説明された分散を取得しようとしていますが、以下のコードはNaNの束を返します。

def test3(df):
    pca.fit(df)
    return pca.explained_variance_ratio_
tmp.rolling(window=5,center=False).apply(lambda x: test3(x))

ただし、説明された独自の分散関数を作成できますが、これも機能しません。

def test4(df):
    cov_mat=np.cov(df.T) #need covariance of features, not observations
    eigen_vals,eigen_vecs=np.linalg.eig(cov_mat)
    tot=sum(eigen_vals)
    var_exp=[(i/tot) for i in sorted(eigen_vals,reverse=True)]
    return var_exp
tmp.rolling(window=5,center=False).apply(lambda x: test4(x))

このエラーが発生します0-dimensional array given. Array must be at least two-dimensional

要約すると、ローリングzスコアを実行し、次に各ロールで説明された分散を出力するローリングpcaを実行したいと思います。私はローリングZスコアを持っていますが、説明された差異はありません。

9
Bobe Kryant

@BrenBarnがコメントしたように、ローリング関数はベクトルを単一の数に減らす必要があります。以下はあなたがやろうとしていたことと同等であり、問​​題を強調するのに役立ちます。

_zscore = lambda x: (x - x.mean()) / x.std()
tmp.rolling(5).apply(zscore)
_
_TypeError: only length-1 arrays can be converted to Python scalars
_

zscore関数では、x.mean()は減少し、x.std()は減少しますが、xは配列です。したがって、全体が配列になります。


これを回避する方法は、問題を引き起こす部分ではなく、それを必要とするzスコア計算の部分でロールを実行することです。

_(tmp - tmp.rolling(5).mean()) / tmp.rolling(5).std()
_

enter image description here

15
piRSquared