2014-10-08 7 views
11

나는 여러 개의 값을 가지고있는 시계열 A을 가지고있다. 우리가 B[0] = 0을 가정 할 수팬더의 재귀 적 정의

B[t] = a * A[t] + b * B[t-1] 

ab 실제 숫자 : 나는 다음과 같이 수학적으로 정의 된 일련의 B를 얻을 필요가있다.

팬더에서 이러한 유형의 순환 계산을 수행 할 방법이 있습니까? 아니면 this answer에서 제안 된대로 파이썬으로 반복 할 수밖에 없습니까? 입력의 예로서

: 내가 코멘트에서 언급 한 바와 같이

> A = pd.Series(np.random.randn(10,)) 

0 -0.310354 
1 -0.739515 
2 -0.065390 
3 0.214966 
4 -0.605490 
5 1.293448 
6 -3.068725 
7 -0.208818 
8 0.930881 
9 1.669210 
+1

개방 문제에 쓸 수 있도록 새 열, B를 만들려면 그것을 cythonize하려면 : https://github.com/pydata/pandas/issues/4567, 그러나 일부 링크도 마찬가지입니다. – Jeff

+2

'scipy.signal.lfilter'를 사용할 수 있습니다. 예제는 http://stackoverflow.com/questions/21336794/python- recursive-vectorization-with-timeseries를 참조하십시오. –

답변

14

, 당신은 scipy.signal.lfilter를 사용할 수 있습니다.

import numpy as np 
from scipy.signal import lfilter 


np.random.seed(123) 

A = np.random.randn(10) 
a = 2.0 
b = 3.0 

# Compute the recursion using lfilter. 
# [a] and [1, -b] are the coefficients of the numerator and 
# denominator, resp., of the filter's transfer function. 
B = lfilter([a], [1, -b], A) 

print B 

# Compare to a simple loop. 
B2 = np.empty(len(A)) 
for k in range(0, len(B2)): 
    if k == 0: 
     B2[k] = a*A[k] 
    else: 
     B2[k] = a*A[k] + b*B2[k-1] 

print B2 

print "max difference:", np.max(np.abs(B2 - B)) 

스크립트의 출력은 다음과 같습니다 :

[ -2.17126121e+00 -4.51909273e+00 -1.29913212e+01 -4.19865530e+01 
    -1.27116859e+02 -3.78047705e+02 -1.13899647e+03 -3.41784725e+03 
    -1.02510099e+04 -3.07547631e+04] 
[ -2.17126121e+00 -4.51909273e+00 -1.29913212e+01 -4.19865530e+01 
    -1.27116859e+02 -3.78047705e+02 -1.13899647e+03 -3.41784725e+03 
    -1.02510099e+04 -3.07547631e+04] 
max difference: 0.0 

B = lfilter([a], [1.0, -b], A) 

여기에 전체 스크립트입니다 :이 경우, 당신이 필요로하는 모든입니다 (A를 가정하고 한 차원 NumPy와 배열)


또 다른 예는 IPython에서 numpy 배열 대신 pandas DataFrame을 사용하는 것입니다.

당신은

In [12]: df = pd.DataFrame([1, 7, 9, 5], columns=['A']) 

In [13]: df 
Out[13]: 
    A 
0 1 
1 7 
2 9 
3 5 

을 가지고 있고 (K < 0 B[k] == 0 포함) B[k] = A[k] + 2*B[k-1], 당신은 여기

In [14]: df['B'] = lfilter([1], [1, -2], df['A'].astype(float)) 

In [15]: df 
Out[15]: 
    A B 
0 1 1 
1 7 9 
2 9 27 
3 5 59 
+0

환상적인 답변입니다. 워렌에게 감사드립니다. 나는 신호와 시스템 (Oppenheim 's book)에서 수업을 들었는데, 그렇게 느낀다. 문제를 해결하는 올바른 방법 인 것 같아서이 답을 자세히 살펴볼 것입니다. 이 접근법은 선형 재귀 만 처리 할 수 ​​있다고 가정합니다. 맞습니까? – Josh

+1

예, 선형입니다. ('lilter'의'l'은'linear '를 의미합니다.) –