Как удалить большой всплеск в начале сигнала после применения полосового фильтра Баттерворта в python?

Я хочу убрать тренд сигнала с помощью полосового фильтра. Я использовал фильтр Баттерворта с FL = 0,1 Гц и FH = 20 Гц в Python, но после применения этого полосового фильтра я заметил большой всплеск в начале сигнала без тренда. к чему этот шип? и как убрать этот шип в питоне?

Как удалить большой всплеск в начале сигнала после применения полосового фильтра Баттерворта в python?

скачать "data1.csv" можно по этой ссылке.

from scipy.signal import butter, lfilter
from numpy import genfromtxt
import numpy as np
import matplotlib.pyplot as plt

def butter_bandpass(lowcut, highcut, fs, order=5):
    nyq = 0.5 * fs
    low = lowcut / nyq
    high = highcut / nyq
    b, a = butter(order, [low, high], btype='band')
    return b, a

def butter_bandpass_filter(data, lowcut, highcut, fs, order=5):
    b, a = butter_bandpass(lowcut, highcut, fs, order=order)
    y = lfilter(b, a, data)
    return y


BP_without_NaN = genfromtxt('data1.csv', delimiter=',')
framerate=1024

# detrending [0.1Hz  20Hz]
OMW = butter_bandpass_filter(data = BP_without_NaN, lowcut = 0.1, highcut = 20 , fs = framerate, order = 3)

# plot OMW
time = np.linspace(0, len(OMW)/framerate ,len(OMW))
plt.plot(time, OMW)
plt.show()

Добро пожаловать в СО! Что вы пробовали до сих пор / пожалуйста, добавьте минимальный, полный и проверяемый пример вашего кода, чтобы мы могли вам помочь!

ti7 18.12.2020 17:46
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python.
Некоторые методы, о которых вы не знали, что они существуют в Python.
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
1
934
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При применении фильтра Баттерворта (или любого другого БИХ-фильтра) каждая выходная выборка вычисляется на основе предыдущих выходных выборок.

y[n] = b0 * x[n] + b1 * x[n-1] + ... + bk * x[n-k]
                 - a1 * y[n-1] + ... + ak * y[n-k]

Это создает проблему для того, как запустить фильтр в начале сигнала, поскольку еще не были вычислены выходные выборки. Типичный способ справиться с этим - предположить, что все выходные данные в отрицательные моменты времени n < 0 равны нулю, или, что то же самое, концептуально экстраполировать входные данные как нулевые. Этот подход с нулевой инициализацией — это то, что scipy.signal.lfilter делает по умолчанию.

Однако такой подход не всегда удобен. Если входной сигнал не начинается близко к нулю, то экстраполяция нулей вносит в сигнал искусственный скачок или разрыв скачка, а выходной сигнал начинается с нежелательного переходного процесса, реакции фильтра на этот искусственный скачок.

Глядя на ваши связанные данные, входные данные начинаются с нескольких сотен выборок, равных 154. Это объясняет большой всплеск в начале вашего графика. В основном вы можете удалить всплеск, изменив инициализацию фильтра. Используйте scipy.signal.lfilter_zi для вычисления начальных условий для lfilter для установившегося состояния переходной характеристики со значением 154:

zi = lfilter_zi(b, a) * data[0]

Затем используйте его с lfilter как y, _ = lfilter(b, a, data, zi=zi). Вот что я получаю с этим изменением:

Другие вопросы по теме