2014-10-08 85 views
11

我有一個時間序列A持有幾個值。我需要獲得一系列B是代數定義如下:熊貓的遞歸定義

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

在這裏我們可以假設B[0] = 0,並ab是實數。

有沒有辦法在熊貓中做這種類型的遞歸計算?或者我不得不按照this answer中的建議循環使用Python?

作爲輸入的例子:

> 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

這裏的開放問題以cythonize它:https://github.com/pydata/pandas/issues/4567,但一些鏈接也是他們的 – Jeff 2014-10-08 23:26:24

+2

你可以使用'scipy.signal.lfilter'。有關示例,請參閱http://stackoverflow.com/questions/21336794/python-recursive-vectorization-with-timeseries。 – 2014-10-08 23:49:25

回答

14

正如我在評論指出的那樣,你可以使用scipy.signal.lfilter。在這種情況下(假設A是一維numpy的陣列),所有你需要的是:

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

下面是一個完整的腳本:

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 

另一個例子,在IPython中,使用熊貓DataFrame而不是numpy數組:

如果你有

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 

,你要創建一個新列,B,使得B[k] = A[k] + 2*B[k-1](與B[k] == 0對於k < 0),你可以寫

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的書),這感覺非常正確。我會仔細研究這個答案,因爲它看起來是解決問題的正確方法。我認爲這種方法只能處理線性遞歸,對嗎? – Josh 2014-10-09 00:25:49

+1

是的,只有線性。 ('lfilter'中的'l'代表'linear'。) – 2014-10-09 00:37:47