熊猫滚动应用自定义

Bob*_*ant 9 python apply pandas

我一直在这里听到类似的答案,但在使用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'])
Run Code Online (Sandbox Code Playgroud)

如果我使用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
Run Code Online (Sandbox Code Playgroud)

我收到这个错误.然而,我可以创建具有平均值和标准偏差的函数,没有任何问题.

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

我相信当我试图通过z-score的当前值减去平均值时会发生错误.

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
Run Code Online (Sandbox Code Playgroud)

如何使用sklearn创建自定义滚动功能以首先标准化然后运行PCA?

编辑:我意识到我的问题并不完全清楚所以我会再试一次.我想标准化我的值,然后运行PCA以获得每个因素解释的方差量.无需滚动即可完成此操作非常简单.

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

滚动时我不能使用相同的程序.使用@piRSquared中的滚动zscore函数给出zscores.似乎sklearn中的PCA与滚动应用自定义函数不兼容.(事实上​​,我认为大多数sklearn模块就是这种情况.)我只是想获得一个一维项目的解释方差,但下面的代码返回一堆NaN.

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

但是,我可以创建自己解释的方差函数,但这也行不通.

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))
Run Code Online (Sandbox Code Playgroud)

我收到这个错误0-dimensional array given. Array must be at least two-dimensional.

回顾一下,我想运行滚动的z分数,然后滚动pca输出每个卷的解释方差.我有滚动的z分数,但没有解释方差.

piR*_*red 16

正如@BrenBarn评论的那样,滚动功能需要将向量减少为单个数字.以下内容相当于您尝试执行的操作,并帮助突出显示问题.

zscore = lambda x: (x - x.mean()) / x.std()
tmp.rolling(5).apply(zscore)
Run Code Online (Sandbox Code Playgroud)
TypeError: only length-1 arrays can be converted to Python scalars
Run Code Online (Sandbox Code Playgroud)

zscore函数中,x.mean()减少,x.std()减少,但是x是一个数组.因此整个事物就是一个数组.


解决这个问题的方法是对需要它的z-score计算部分执行滚动,而不是对导致问题的部分执行滚动.

(tmp - tmp.rolling(5).mean()) / tmp.rolling(5).std()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Jer*_*y T 5

由于 lambda 函数中的 x 表示(滚动)系列/ndarray,因此 lambda 函数可以这样编码(其中 x[-1] 指的是当前滚动数据点):

zscore = lambda x: (x[-1] - x.mean()) / x.std(ddof=1)
Run Code Online (Sandbox Code Playgroud)

然后就可以调用了:

tmp.rolling(5).apply(zscore)
Run Code Online (Sandbox Code Playgroud)

还注意到自由度默认为 1tmp.rolling(5).std() 为了产生与@piRSquared 相同的结果,必须为 指定 ddof x.std(),默认为 0。--花了很长时间才弄清楚这一点!

  • 嗨,Jerry,在尝试您的答案时,我在 x[-1] 上遇到了关键错误。x 属于 pandas.core.series.Series 类。使用 x.values[-1] 解决了我的问题。 (3认同)