Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在python中实现连续时间高通/低通滤波器?_Python_Numpy_Scipy_Filtering - Fatal编程技术网

如何在python中实现连续时间高通/低通滤波器?

如何在python中实现连续时间高通/低通滤波器?,python,numpy,scipy,filtering,Python,Numpy,Scipy,Filtering,我有一个应用程序,接收固定频率的输入信号。我一直在尝试为这个传入信号实现一个过滤器,而不必节省N个时间步并对其执行过滤功能。我想做的是类似于一维卡尔曼滤波器,我用新的观测值更新我的当前状态。我不是数学家,因此维基百科关于这是否可能的页面对我来说是完全无法理解的。此外,这个域中的StackOverflow答案(我已经发现)只考虑是否有N个时间步的信号可用,以及如何对其执行过滤,我可以毫无问题地进行过滤 我在下面提供了一些虚拟代码,说明了我一直试图编写的函数类型 import numpy as np

我有一个应用程序,接收固定频率的输入信号。我一直在尝试为这个传入信号实现一个过滤器,而不必节省N个时间步并对其执行过滤功能。我想做的是类似于一维卡尔曼滤波器,我用新的观测值更新我的当前状态。我不是数学家,因此维基百科关于这是否可能的页面对我来说是完全无法理解的。此外,这个域中的StackOverflow答案(我已经发现)只考虑是否有N个时间步的信号可用,以及如何对其执行过滤,我可以毫无问题地进行过滤

我在下面提供了一些虚拟代码,说明了我一直试图编写的函数类型

import numpy as np
import matplotlib.pyplot as plt

def high_pass(new, previous, cutoff=20):
    # Howto?
    return 0

def low_pass(new, previous, cutofff=20):
    # Howto?
    return 0

def continuous_filter(vs):
    prev_highpass, prev_lowpass = 0, 0
    for v in vs:
        prev_highpass = high_pass(v, prev_highpass)
        prev_lowpass = low_pass(v, prev_lowpass)
        yield prev_highpass, prev_lowpass


np.random.seed(21)
sec_duration = 10.0
time_resolution = 1e3
dt = 1/time_resolution
steps = int(sec_duration * time_resolution)
signal = np.sum([np.sin(np.linspace(0, np.random.randint(10, 100), steps)) * np.random.random() for _ in range(3)], axis=0)

filt_signals = np.array([[high, low] for high, low in continuous_filter(signal)])

plt.plot(signal, label="Input signal")
plt.plot(filt_signals[:, 0], label="High-pass")
plt.plot(filt_signals[:, 1], label="Low pass")
plt.legend()
plt.show()


有人能告诉我这是否可能吗?我一直在看SciPy,但我不理解它。

首先,你需要一个截止时间的过滤器时间常数:
alpha=dt/(RC+dt)
截止时间=1/(2*pi*RC)

您需要此因子来计算下一个过滤值:

def low_pass(x_new, y_old, cutoff=20):
    alpha = dt / (dt + 1 / (2 * np.pi * cutoff))
    y_new = x_new * alpha + (1 - alpha) * y_old
    return y_new
来自维基百科:

来自维基百科:


首先,您需要从截止点为过滤器设置一个时间常数:
alpha=dt/(RC+dt)
cutoff=1/(2*pi*RC)

您需要此因子来计算下一个过滤值:

def low_pass(x_new, y_old, cutoff=20):
    alpha = dt / (dt + 1 / (2 * np.pi * cutoff))
    y_new = x_new * alpha + (1 - alpha) * y_old
    return y_new
来自维基百科:

来自维基百科:


这是一个很好的回答,多利安,谢谢你。经过多年的阴影堆栈溢出,这将是我的第一个贡献。它是次要的,希望它有助于扩展用例。尽可能多地保留原始符号,以便于跟踪

只需要两次进口

'''python
import numpy as np
import matplotlib.pyplot as plt
对rc_高通量α值的轻微修正

def rc_low_pass(x_new, y_old, sample_rate_hz, lowpass_cutoff_hz):
    dt = 1/sample_rate_hz
    rc = 1/(2*np.pi*lowpass_cutoff_hz)
    alpha = dt/(rc + dt)
    y_new = x_new * alpha + (1 - alpha) * y_old
    return y_new


def rc_high_pass(x_new, x_old, y_old, sample_rate_hz, highpass_cutoff_hz):
    dt = 1/sample_rate_hz
    rc = 1/(2*np.pi*highpass_cutoff_hz)
    alpha = rc/(rc + dt)
    y_new = alpha * (y_old + x_new - x_old)
    return y_new


def rc_filters(xs, sample_rate_hz, 
               highpass_cutoff_hz, 
               lowpass_cutoff_hz):
    # Initialize. This can be improved to match wikipedia.
    x_prev = 0
    y_prev_high = 0
    y_prev_low = 0

    for x in xs:
        y_prev_high = rc_high_pass(x, x_prev, y_prev_high, sample_rate_hz, 
                                   highpass_cutoff_hz)
        y_prev_low = rc_low_pass(x, y_prev_low, sample_rate_hz, 
                                 lowpass_cutoff_hz)
        x_prev = x
        yield y_prev_high, y_prev_low
现在转到主屏幕,我使用赫兹和秒的物理单位。请原谅基数为2的数字表示法,它有助于为FFT设置舞台

if __name__ == "__main__":
    """
    # RC filters for continuous signals
    """
    sample_rate = 2**13  # Close to 8 kHz
    duration_points = 2**10
    sec_duration = duration_points/sample_rate

    frequency_low = sample_rate/2**9
    frequency_high = sample_rate/2**3

    # Design the cutoff
    number_octaves = 3
    highpass_cutoff = frequency_high/2**number_octaves
    lowpass_cutoff = frequency_low*2**number_octaves

    print('Two-tone test')
    print('Sample rate, Hz:', sample_rate)
    print('Record duration, s:', sec_duration)
    print('Low, high tone frequency:', frequency_low, frequency_high)

    time_s = np.arange(duration_points)/sample_rate

    sig = np.sin(2*np.pi*frequency_low*time_s) + \
          np.sin(2*np.pi*frequency_high*time_s)

    filt_signals = np.array([[high, low]
                             for high, low in
                             rc_filters(sig, sample_rate,
                                        highpass_cutoff, lowpass_cutoff)])
输入信号不同,更接近我的典型用例,结果图显示通常的RC滤波器不是很快。这是一个经典的解决方案,在这里使用它很好

plt.plot(sig, label="Input signal")
plt.plot(filt_signals[:, 0], label="High-pass")
plt.plot(filt_signals[:, 1], label="Low-pass")
plt.title("RC Low-pass and High-pass Filter Response")
plt.legend()
plt.show()

这是一个很好的回答,多利安,谢谢你。经过多年的阴影堆栈溢出,这将是我的第一个贡献。它是次要的,希望它有助于扩展用例。尽可能多地保留原始符号,以便于跟踪

只需要两次进口

'''python
import numpy as np
import matplotlib.pyplot as plt
对rc_高通量α值的轻微修正

def rc_low_pass(x_new, y_old, sample_rate_hz, lowpass_cutoff_hz):
    dt = 1/sample_rate_hz
    rc = 1/(2*np.pi*lowpass_cutoff_hz)
    alpha = dt/(rc + dt)
    y_new = x_new * alpha + (1 - alpha) * y_old
    return y_new


def rc_high_pass(x_new, x_old, y_old, sample_rate_hz, highpass_cutoff_hz):
    dt = 1/sample_rate_hz
    rc = 1/(2*np.pi*highpass_cutoff_hz)
    alpha = rc/(rc + dt)
    y_new = alpha * (y_old + x_new - x_old)
    return y_new


def rc_filters(xs, sample_rate_hz, 
               highpass_cutoff_hz, 
               lowpass_cutoff_hz):
    # Initialize. This can be improved to match wikipedia.
    x_prev = 0
    y_prev_high = 0
    y_prev_low = 0

    for x in xs:
        y_prev_high = rc_high_pass(x, x_prev, y_prev_high, sample_rate_hz, 
                                   highpass_cutoff_hz)
        y_prev_low = rc_low_pass(x, y_prev_low, sample_rate_hz, 
                                 lowpass_cutoff_hz)
        x_prev = x
        yield y_prev_high, y_prev_low
现在转到主屏幕,我使用赫兹和秒的物理单位。请原谅基数为2的数字表示法,它有助于为FFT设置舞台

if __name__ == "__main__":
    """
    # RC filters for continuous signals
    """
    sample_rate = 2**13  # Close to 8 kHz
    duration_points = 2**10
    sec_duration = duration_points/sample_rate

    frequency_low = sample_rate/2**9
    frequency_high = sample_rate/2**3

    # Design the cutoff
    number_octaves = 3
    highpass_cutoff = frequency_high/2**number_octaves
    lowpass_cutoff = frequency_low*2**number_octaves

    print('Two-tone test')
    print('Sample rate, Hz:', sample_rate)
    print('Record duration, s:', sec_duration)
    print('Low, high tone frequency:', frequency_low, frequency_high)

    time_s = np.arange(duration_points)/sample_rate

    sig = np.sin(2*np.pi*frequency_low*time_s) + \
          np.sin(2*np.pi*frequency_high*time_s)

    filt_signals = np.array([[high, low]
                             for high, low in
                             rc_filters(sig, sample_rate,
                                        highpass_cutoff, lowpass_cutoff)])
输入信号不同,更接近我的典型用例,结果图显示通常的RC滤波器不是很快。这是一个经典的解决方案,在这里使用它很好

plt.plot(sig, label="Input signal")
plt.plot(filt_signals[:, 0], label="High-pass")
plt.plot(filt_signals[:, 1], label="Low-pass")
plt.title("RC Low-pass and High-pass Filter Response")
plt.legend()
plt.show()

太好了!但是,代码中有一个小错误。高通函数中的截止参数需要松开一个“f”。我不能做那个编辑,因为它是太小,根据其他评论:没有连续时间这样的事情,你总是在看离散的步骤。这只是对你的问题的补充。太好了!但是,代码中有一个小错误。高通函数中的截止参数需要松开一个“f”。我不能做那个编辑,因为它是太小,根据其他评论:没有连续时间这样的事情,你总是在看离散的步骤。这是一个很好的答案,谢谢。您是指谁?对于主要解决方案贡献者,感谢您指出这一点。这是一个很好的答案,谢谢。您是指谁?对于主要解决方案贡献者,感谢您指出这一点。在这方面我是新手。