具有沿N-D阵列的任何轴施加的初始条件的SciPy滤波器

时间:2015-02-23 20:54:17

标签: python numpy scipy filtering

根据lfilter的SciPy文档:

zi:array_like,可选 过滤器延迟的初始条件。它是长度为max(len(a),len(b))-1的向量(或N维输入的向量数组)。如果zi为None或未给出,则假定初始休息。有关更多信息,请参阅lfiltic。

以下代码调用lfilter,并使用lfilter_zi传递zi,使得zi的最后一个维度的长度为max(len(a),len(b))-1。但是它会引发错误,具体取决于应用程序轴:

import numpy as np
import scipy.signal as sig

def apply_filter(B, A, signal, axis=-1):
   # apply filter, setting proper initial state (doesn't assume rest)
   filtered, zf = sig.lfilter(B, A, signal, 
             zi=sig.lfilter_zi(B, A) * np.take(signal, 0, axis=axis)[..., np.newaxis], axis=axis)
   return filtered

B, A = sig.butter(1, 0.5)
x = np.random.randn(12, 50)
apply_filter(B, A, x, axis=1)    # works without error
apply_filter(B, A, x, axis=0)    # raises ValueError

ValueError: The number of initial conditions must be max([len(a),len(b)]) - 1

如何避免错误,并在不假设初始休息的情况下沿任意轴应用过滤器?

1 个答案:

答案 0 :(得分:1)

zi中的初始条件必须与赋予lfilter的轴在同一轴上。改变这个:

np.take(signal, 0, axis=axis)[..., np.newaxis]

np.take(signal, [0], axis=axis)

np.take(signal, 0, axis=axis)np.take(signal, [0], axis=axis)之间的区别在于后者保留了维度数。 E.g。

In [105]: signal
Out[105]: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

In [106]: signal.shape
Out[106]: (3, 5)

如果我们take来自轴1的第一个索引,我们得到一个形状为(1,)的1-d数组:

In [107]: a = np.take(signal, 0, axis=1)

In [108]: a.shape
Out[108]: (3,)

In [109]: a
Out[109]: array([ 0,  5, 10])

相反,如果我们在[0]参数中使用列表indices,我们会得到一个形状为(3,1)的数组:

In [110]: b = np.take(signal, [0], axis=1)

In [111]: b.shape
Out[111]: (3, 1)

In [112]: b
Out[112]: 
array([[ 0],
       [ 5],
       [10]])