Я хотел разложить следующий сигнал, массив numpy:
В настоящее время я использую функцию Season_decompose из statsmodels.tsa. Seasonal: https://www.statsmodels.org/dev/generated/statsmodels.tsa. Seasonal. Seasonal_decompose.html
Мой код:
myPeriod = 60
decompose_result_mult = seasonal_decompose(mySignal,
model = "additive",period=myPeriod)
trend = decompose_result_mult.trend
seasonal = decompose_result_mult.seasonal
residual = decompose_result_mult.resid
moyen=trend
tempo=residual+seasonal
И что я получаю, когда рисую переменные мойен (оранжевый) и темп (зеленый):
Значением по умолчанию, используемым для тренда, является среднее значение сигнала, и тогда переменная темпа может быть отрицательной. Можно ли добиться того же, но взяв «минимальное значение» вместо «среднего значения» функции? Это привело бы к тому, что переменная темпа была бы только положительной. Чтобы проиллюстрировать то, что я имею в виду, можно было бы использовать что-то вроде следующей красной линии в качестве данных «тренда» и получить соответствующие данные о темпе:
Как я могу этого добиться (я не нашел, как изменить способ работы Season_decompose или как добиться этого с помощью других функций)?
Я не вижу проблемы. Если хотите, вы можете сместить линии по осям Y. Кроме того, доступен исходный код метода statsmodels.org/dev/_modules/statsmodels/tsa/… вы можете изменить функцию seasonal_mean
для вывода минимального значения вместо среднего.
Вы можете использовать алгоритм «катящегося шара», реализованный, например, в scikit-image (см. здесь). Пример (с некоторыми поддельными данными, немного похожими на ваши):
import numpy as np
from matplotlib import pyplot as plt
from scipy.signal import butter, lfilter
from skimage import restoration
# some fake data (low pass filtered to look a bit more like the data in the original question)
t = np.linspace(0, 10, 500)
x = np.random.randn(len(t))
b, a = butter(3, 0.25, btype = "low")
xf = lfilter(b, a, x)
xf -= xf[0]
xf += 3 * t
fig, ax = plt.subplots()
ax.plot(t, xf, label = "data")
# get "background" using rolling ball algorithm
background = restoration.rolling_ball(xf, radius=50)
ax.plot(t, background, label = "background")
ax.plot(t, xf - background, label = "residual")
ax.legend()
Вы можете поиграть со значением radius
, если это необходимо для вашей проблемы.
Это сработало, как задумано, спасибо! :)
Самый простой способ получить то, что вы хотите, — создать новую запись данных, содержащую только локальные минимумы исходного набора данных. Затем вычислите мойен из этого. Не могу гарантировать, что это сделает темп полностью положительным, но он должен быть достаточно близким, чтобы вы могли добавить небольшую константу, чтобы сделать его таким.