使用rolling_apply进行pandas的Python自定义函数

时间:2014-01-09 16:29:22

标签: python pandas

我想使用pandas.rolling_apply函数在滚动窗口的基础上应用我自己的自定义函数。

但我的函数需要两个参数,并且还有两个输出。这可能吗?

以下是可重复的最低范例......

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

def gm(df,p):
    v =(((df+1).cumprod())-1)*p
    return v.iloc[-1]

# an example output when subsetting for just 2001
gm(tmp['2001'],5)


# the aim is to do it on a rolling basis over a 50 day window
# whilst also getting both outputs and also allows me to add in the parameter p=5
# or any other number I want p to be... 
pd.rolling_apply(tmp,50,gm)

导致错误......因为gm有两个参数......

任何帮助将不胜感激......

修改

根据Jeff的评论,我已经取得了进展,但仍然在努力争取两个或更多列输出,所以如果我做了一个新函数(下面),它只返回两个随机数(与之前的计算无关)而不是最后一个v行,我得到TypeError: only length-1 arrays can be converted to Python scalars的错误。如果

,此功能有效
def gm2(df,p):
    df = pd.DataFrame(df)
    v =(((df+1).cumprod())-1)*p
    return np.random.rand(2)

pd.rolling_apply(tmp,50,lambda x: gm2(x,5)).tail(20)

如果2更改为1 ...

,此功能有效

1 个答案:

答案 0 :(得分:14)

rolling_apply将numpy数组传递给应用函数(at at the moment),0.14它应该传递一个帧。问题是here

因此,重新定义您的函数以处理numpy数组。 (你当然可以在这里构建一个DataFrame,但你的索引/列名不一样。)

In [9]: def gm(df,p):
   ...:     v = ((np.cumprod(df+1))-1)*p
   ...:     return v[-1]
   ...: 

如果您想在自定义功能中使用更多pandas功能,请执行此操作(请注意,呼叫帧的指示已通过ATM)。

def gm(arr,p):
    df = DataFrame(arr)
    v =(((df+1).cumprod())-1)*p
    return v.iloc[-1]

通过lambda传递

In [11]: pd.rolling_apply(tmp,50,lambda x: gm(x,5)).tail(20)
Out[11]: 
                   A         B
2006-06-04  0.004207 -0.002112
2006-06-05  0.003880 -0.001598
2006-06-06  0.003809 -0.002228
2006-06-07  0.002840 -0.003938
2006-06-08  0.002855 -0.004921
2006-06-09  0.002450 -0.004614
2006-06-10  0.001809 -0.004409
2006-06-11  0.001445 -0.005959
2006-06-12  0.001297 -0.006831
2006-06-13  0.000869 -0.007878
2006-06-14  0.000359 -0.008102
2006-06-15 -0.000885 -0.007996
2006-06-16 -0.001838 -0.008230
2006-06-17 -0.003036 -0.008658
2006-06-18 -0.002280 -0.008552
2006-06-19 -0.001398 -0.007831
2006-06-20 -0.000648 -0.007828
2006-06-21 -0.000799 -0.007616
2006-06-22 -0.001096 -0.006740
2006-06-23 -0.001160 -0.006004

[20 rows x 2 columns]