简体   繁体   English

SciPy lfilter 用于任意滤波器,初始条件沿 ND 阵列的任何轴应用

[英]SciPy lfilter for arbitrary filter, with initial conditions applied along any axis of N-D array

This python numpy/Scipy question SciPy lfilter with initial conditions applied along any axis of ND array has an answer that works well when the operation axis!=0 , or when the length of the initial condition vector zi remains 1, ie for a first-order filter.这个 python numpy/Scipy 问题SciPy 沿 ND 数组的任何轴应用初始条件的 lfilter有一个答案,当操作axis!=0时,或者当初始条件向量zi的长度保持为 1 时,即对于第一个 -订单过滤器。 It fails as soon as a higher order filter is defined to operate on an input axis assigned to the first axis of signal , where signal is 2D.一旦高阶滤波器被定义为在分配给signal的第一轴的输入axis运行,它就会失败,其中signal是二维的。

For example:例如:

import numpy as np
from scipy.signal import (lfilter, lfilter_zi, butter)

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

B, A = 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)    # works without error


B, A = butter(2, 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 error

raises加薪

ValueError: operands could not be broadcast together with shapes (2,) (1,50)

How could the solution be made more general to apply to an arbitrary filter length for axis=0 ?如何使解决方案更通用以适用于axis=0的任意滤波器长度?

Your error came from the shape of your arrays when * these two array.*这两个数组时,您的错误来自 arrays 的形状。 Simple example:简单示例:

>>> np.random.rand(2) * np.random.rand(1,10) 
----> 1 np.random.rand(2) * np.random.rand(1,10)

ValueError: operands could not be broadcast together with shapes (2,) (1,10) 


>>> np.random.rand(2)[:,None] * np.random.rand(1,10) 
array([[0.05905608, 0.30028617, 0.12495555, 0.28012041, 0.15031258,
        0.05166653, 0.2035891 , 0.01499304, 0.31749996, 0.3146938 ],
       [0.06860488, 0.34883958, 0.14515967, 0.3254132 , 0.17461669,
        0.06002052, 0.23650752, 0.01741727, 0.36883668, 0.36557679]])

For handling different axis in your function you can write the function like the below:为了处理 function 中的不同轴,您可以像下面这样编写 function:

def apply_filter(B, A, signal, axis=-1):
    tmp = lfilter_zi(B, A) if axis==1 else lfilter_zi(B, A)[:,None]
    filtered, zf = lfilter(B, A, signal, zi = tmp * np.take(signal, [0], axis=axis), axis=axis)
    return filtered

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM