将scipy过滤器应用于多维数据

时间:2020-03-08 03:52:32

标签: numpy scipy signal-processing

我有一个由(2500, 2)形状的numpy数组表示的立体声音频数据。我想使用scipy的signal.sosflt()函数对其进行过滤,但是我得到了:

ValueError: Invalid zi shape. With axis=0, an input with shape (2500, 2), and an sos array with 2 sections, zi must have shape (2, 2, 2), got (2, 2).

代码中唯一的复杂性是我在处理第一个缓冲区时初始化一次zi,然后使用它在后续调用中对过滤器进行条件处理:

from scipy import signal

def setup():
    zi = None
    # define a narrow band filter centered around 440 Hz.
    sos = signal.butter(2, [438, 442], btype='bandpass', output='sos', fs=48000)

def process(src, dst):
    # src and dst shape = (2500, 0)
    if zi is None:
        zi = signal.sosfilt_zi(sos)  # initialize zi on first buffer
    dst, zi = signal.sosfilt(sos, src, axis=0, zi=zi)

(注意:我尝试过axis=-1axis=1,但都不正确。)

1 个答案:

答案 0 :(得分:1)

一种解决方案,但也许不是最干净的:

由于源数据是立体声,因此sosfilt需要两份zi,每个通道一个。以下内容将起作用,但是如果src有两列,则

from scipy import signal

def setup():
    zi = None
    # define a narrow band filter centered around 440 Hz.
    sos = signal.butter(2, [438, 442], btype='bandpass', output='sos', fs=48000)

def process(src, dst):
    # src and dst shape = (2500, 0)
    if zi is None:
        tmp = signal.sosfilt_zi(sos)
        zi = [tmp, tmp]               # assumes source data has two columns
    dst, zi = signal.sosfilt(sos, src, axis=0, zi=zi)

这可行,但是更通用的解决方案是根据源数据的形状初始化zi