Предположим, у нас есть набор данных, который может быть дан примерно
import numpy as np
x = np.linspace(0,2*np.pi,100)
y = np.sin(x) + np.random.random(100) * 0.2
Поэтому у нас есть вариация 20% набора данных. Моя первая идея состояла в том, чтобы использовать функцию Scivy UnivariateSpline, но проблема в том, что это не учитывает небольшой шум в хорошем смысле. Если вы рассматриваете частоты, фон намного меньше сигнала, поэтому сплайном только среза может быть идея, но это может включать в себя преобразование Фурье назад и вперед, что может привести к плохому поведению. Другим способом будет скользящее среднее, но для этого также потребуется правильный выбор задержки.
Любые советы / книги или ссылки, как решить эту проблему?
python
numpy
scipy
signal-processing
data-processing
varantir
источник
источник
Ответы:
Я предпочитаю фильтр Савицкого-Голея . Он использует метод наименьших квадратов для регрессии небольшого окна ваших данных в полином, а затем использует полином для оценки точки в центре окна. Наконец, окно сдвигается вперед на одну точку данных, и процесс повторяется. Это продолжается до тех пор, пока каждая точка не будет оптимально отрегулирована относительно ее соседей. Он отлично работает даже с шумными выборками из непериодических и нелинейных источников.
Вот подробный пример поваренной книги . Посмотрите мой код ниже, чтобы понять, как легко им пользоваться. Примечание: я пропустил код для определения
savitzky_golay()
функции, потому что вы можете буквально скопировать / вставить ее из примера поваренной книги, который я привел выше.ОБНОВЛЕНИЕ: до меня дошло, что пример поваренной книги, на который я ссылался, был удален. К счастью, фильтр Савицкого-Голея был включен в библиотеку SciPy , на что указывает @dodohjk . Чтобы адаптировать приведенный выше код с использованием исходного кода SciPy, введите:
источник
savgol_filter((x, y), ...)
.Быстрый и грязный способ сглаживания данных, которые я использую, на основе блока скользящего среднего (путем свертки):
источник
scipy.ndimage.filters.convolve1d()
позволяет указать ось nd-массива для фильтрации. Но я думаю, что оба страдают от некоторых проблем в замаскированных ценностях.Если вы заинтересованы в «гладкой» версии сигнала, которая является периодической (как ваш пример), тогда БПФ - правильный путь. Возьмите преобразование Фурье и вычтите низкочастотные частоты:
Даже если ваш сигнал не является полностью периодическим, это позволит отлично вычесть белый шум. Существует много типов фильтров (высокочастотный, низкочастотный и т. Д.), Подходящий из которых зависит от того, что вы ищете.
источник
Подгонка скользящего среднего к вашим данным сгладит шум, посмотрите этот ответ, чтобы узнать, как это сделать.
Если вы хотите использовать LOWESS, чтобы соответствовать вашим данным (это похоже на скользящее среднее, но более изощренно), вы можете сделать это с помощью библиотеки statsmodels :
Наконец, если вы знаете функциональную форму вашего сигнала, вы можете подогнать кривую к вашим данным, что, вероятно, будет лучшим решением.
источник
loess
реализовано.Другой вариант - использовать KernelReg в statsmodels :
источник
Проверь это! Существует четкое определение сглаживания 1D сигнала.
http://scipy-cookbook.readthedocs.io/items/SignalSmooth.html
Клавиши быстрого доступа:
источник
Если вы строите график временных рядов и используете mtplotlib для рисования графиков, используйте метод медианы для сглаживания графика.
где
timeseries
ваш набор данных передается вы можете изменитьwindowsize
для более сглаживания.источник