Recursion: IIR filter with `scipy.lfilter`

前端 未结 2 734
南旧
南旧 2021-01-24 03:32

Given some data x:

from pandas_datareader.data import DataReader as dr
x = np.squeeze(dr(\'DTWEXB\', \'fred\').dropna().values)

I

相关标签:
2条回答
  • 2021-01-24 03:39

    Take the z-transform of your filter, that gives you the values for the numerator b and denominator a:

           alpha
    y(z) = ------------------ x(z)
           1 - (1-alpha) z^-1
    

    So you run

    import scipy.signal
    x[0] /= alpha
    y = scipy.signal.lfilter([alpha], [1, - 1 + alpha], x)
    

    Which yields

    array([ 101.1818    ,  101.176862  ,  101.16819314, ...,  120.9813121 ,
            120.92484874,  120.85786628])
    

    Note I have scaled x[0] to account for the initial condition you wanted.

    0 讨论(0)
  • 2021-01-24 03:41

    The correct arguments for the coefficients of the transfer function are [a] and [1, -b].

    To handle your desired initial condition, you can create the correct initial state for the filter using scipy.signal.lfiltic:

    zi = lfiltic([a], [1, -b], y=[x[0]])
    

    Then call lfilter with the zi argument:

    y, zo = lfilter([a], [1, -b], x, zi=zi)
    

    Here are an x, y (computed using lfilter with zi), and your true_y:

    In [37]: x
    Out[37]: array([ 3.,  1.,  2.,  0., -1.,  2.])
    
    In [38]: y
    Out[38]: 
    array([ 3.        ,  2.94      ,  2.9118    ,  2.824446  ,  2.70971262,
            2.68842124])
    
    In [39]: true_y
    Out[39]: 
    array([ 3.        ,  2.94      ,  2.9118    ,  2.824446  ,  2.70971262,
            2.68842124])
    
    0 讨论(0)
提交回复
热议问题