2014-10-08 12 views
11

में रिकर्सिव परिभाषाएं मेरे पास समय-श्रृंखला A कई मान रखती है।पांडस

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

जहाँ हम B[0] = 0 मान सकते हैं, और a और b वास्तविक संख्याएं हैं: मैं एक श्रृंखला 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

खुला मुद्दा लिख ​​सकते हैं बनाना चाहते हैं इसे cythonize करने के लिए: https://github.com/pydata/pandas/issues/4567, लेकिन कुछ लिंक उनके साथ हैं – Jeff

+2

आप 'scipy.signal.lfilter' का उपयोग कर सकते हैं। उदाहरण के लिए http://stackoverflow.com/questions/21336794/python-recursive-vectorization-with- टाइम्सरीज देखें। –

उत्तर

14

जैसा कि मैंने एक टिप्पणी में बताया गया है, आप scipy.signal.lfilter उपयोग कर सकते हैं। इस मामले में (यह मानते हुए A एक आयामी numpy सारणी है), आप सभी की जरूरत है:

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) 

यहां एक संपूर्ण स्क्रिप्ट है


एक और उदाहरण, आईपीथॉन में, एक अंडाकार सरणी के बजाय एक पांडा डेटाफ्रेम का उपयोग करके:

आप

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] (के < 0 के लिए B[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

शानदार जवाब। धन्यवाद वॉरेन। मैंने सिग्नल और सिस्टम (ओपेनहेम की पुस्तक) में कक्षाएं लीं, और यह बहुत सही लगता है। मैं इस जवाब को ध्यान से देखूंगा, क्योंकि ऐसा लगता है कि समस्या को हल करने का यह सही तरीका है। मुझे लगता है कि यह दृष्टिकोण केवल रैखिक रिकर्सन को संभाल सकता है, सही? – Josh

+1

हां, केवल रैखिक। ('Lfilter' में' l' 'रैखिक' के लिए खड़ा है।) –