2014-01-10 4 views
10

Python custom function using rolling_apply for pandas에 이어 rolling_apply을 사용합니다. 약간이 걸릴 기능을 이전Python pandas rolling_apply 함수에 2 열 입력

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): 
    df = pd.DataFrame(df) 
    v =((((df['A']+df['B'])+1).cumprod())-1)*p 
    return v.iloc[-1] 

그것은 다음 오류 발생 :

pd.rolling_apply(tmp,50,lambda x: gm(x,5)) 

    KeyError: u'no item named A' 

I 람다 함수에 대한 입력은 길이 (50)과 첫 번째 열의의 ndarray이기 때문이라고 생각을하고, 두하지 않는다 열을 입력으로 사용합니다. 두 열을 입력으로 가져와 rolling_apply 함수에서 사용하는 방법이 있습니까? 또 어떤 도움을 크게 감상 할 수

...

답변

1

모든 rolling_ * 함수는 1D 배열에서 작동합니다. 나는 하나의 2 차원 배열을 전달하는 몇 가지 해결 방법을 발명 할 수 있는지 해요,하지만 귀하의 경우, 당신은 롤링 평가 단순히 미리 계산 행 방향 값을 수 있습니다 Using rolling_apply on a DataFrame object 다음은이 질문의 다른 버전

>>> def gm(x,p): 
...  return ((np.cumprod(x) - 1)*p)[-1] 
... 
>>> pd.rolling_apply(tmp['A']+tmp['B']+1, 50, lambda x: gm(x,5)) 
2001-01-01 NaN 
2001-01-02 NaN 
2001-01-03 NaN 
2001-01-04 NaN 
2001-01-05 NaN 
2001-01-06 NaN 
2001-01-07 NaN 
2001-01-08 NaN 
2001-01-09 NaN 
2001-01-10 NaN 
2001-01-11 NaN 
2001-01-12 NaN 
2001-01-13 NaN 
2001-01-14 NaN 
2001-01-15 NaN 
... 
2006-06-09 -0.000062 
2006-06-10 -0.000128 
2006-06-11 0.000185 
2006-06-12 -0.000113 
2006-06-13 -0.000962 
2006-06-14 -0.001248 
2006-06-15 -0.001962 
2006-06-16 -0.003820 
2006-06-17 -0.003412 
2006-06-18 -0.002971 
2006-06-19 -0.003882 
2006-06-20 -0.003546 
2006-06-21 -0.002226 
2006-06-22 -0.002058 
2006-06-23 -0.000553 
Freq: D, Length: 2000 
+0

고맙지 만'gm'의 예시적인 기능은 단순히 모의 예이었다 .. . so 나는 아직도 주위에 해결하려고하는 것이 두 개 이상의 열을 얻는 것을 알고 싶어합니다 ... –

1

을합니다. 함수가 Series를 반환하면 이것을 사용하십시오.

귀하의 스칼라가 반환되므로이 작업을 수행하십시오.

In [71]: df = pd.DataFrame(np.random.randn(2000,2)/10000, 
        index=pd.date_range('2001-01-01',periods=2000), 
        columns=['A','B']) 

가 계산되어 사용할 지수와 스칼라 값 튜플을 반환하는 함수를 재정의합니다. 이것은 우리가 첫 번째 인덱스를 반환 할 때와 약간 다르다는 점에 유의하십시오 (일반적으로 반환되는 마지막 인덱스가 아니라, 둘 중 하나를 수행 할 수 있음).

In [72]: def gm(df,p): 
       v =((((df['A']+df['B'])+1).cumprod())-1)*p 
       return (df.index[0],v.iloc[-1]) 


In [73]: Series(dict([ gm(df.iloc[i:min((i+1)+50,len(df)-1)],5) for i in xrange(len(df)-50) ])) 

Out[73]: 
2001-01-01 0.000218 
2001-01-02 -0.001048 
2001-01-03 -0.002128 
2001-01-04 -0.003590 
2001-01-05 -0.004636 
2001-01-06 -0.005377 
2001-01-07 -0.004151 
2001-01-08 -0.005155 
2001-01-09 -0.004019 
2001-01-10 -0.004912 
2001-01-11 -0.005447 
2001-01-12 -0.005258 
2001-01-13 -0.004437 
2001-01-14 -0.004207 
2001-01-15 -0.004073 
... 
2006-04-20 -0.006612 
2006-04-21 -0.006299 
2006-04-22 -0.006320 
2006-04-23 -0.005690 
2006-04-24 -0.004316 
2006-04-25 -0.003821 
2006-04-26 -0.005102 
2006-04-27 -0.004760 
2006-04-28 -0.003832 
2006-04-29 -0.004123 
2006-04-30 -0.004241 
2006-05-01 -0.004684 
2006-05-02 -0.002993 
2006-05-03 -0.003938 
2006-05-04 -0.003528 
Length: 1950 
5

는 ndarray (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.stats.moments.rolling_apply.html?highlight=rolling_apply#pandas.stats.moments.rolling_apply)에 사용자 FUNC의 입력을 변환하려고합니다 rolling_apply처럼 보인다.

유전자 기능을 조작 내부 창을 선택하는 데 사용되는 보조 열 II 사용에 기반 해결책 : 해당위한

import pandas as pd 
import numpy as np 
import random 

tmp = pd.DataFrame(np.random.randn(2000,2)/10000, columns=['A','B']) 
tmp['date'] = pd.date_range('2001-01-01',periods=2000) 
tmp['ii'] = range(len(tmp))    

def gm(ii, df, p): 
    x_df = df.iloc[map(int, ii)] 
    #print x_df 
    v =((((x_df['A']+x_df['B'])+1).cumprod())-1)*p 
    #print v 
    return v.iloc[-1] 

#print tmp.head() 
res = pd.rolling_apply(tmp.ii, 50, lambda x: gm(x, tmp, 5)) 
print res 
+0

이것은 매끄러운입니다. 나는 그것을 좋아한다. – 8one6

+0

이 정신에서 인덱스가 다중 인덱스 인 경우 어떻게 비슷한 해킹을 시도 할 수 있습니까? 또는 수치가 아닌 인덱스가 중요합니까? 먼저 인덱스를 부동으로 변환해야합니까? – 8one6

+0

색인이 더 이상 사용되지 않도록 내 대답이 수정되었습니다. gm 여전히 배열의 배열을 점점 그래서 그들을 ints iloc 함께 사용할 매핑 할 수있다. – lowtech