Ваша проблема связана с вектором времени (который имеет 1 измерение).Вам нужно будет применить какой-то фильтр к этому вектору.
Первое, что пришло в голову, это medfilt
(медианный фильтр) из scipy
, и это выглядит примерно так:
from scipy.signal import medfilt
l1 = [0, 10, 20, 30, 2, 50, 70, 15, 90, 100]
l2 = medfilt(l1)
print(l2)
результат этого будет:
[ 0. 10. 20. 20. 30. 50. 50. 70. 90. 90.]
проблема этого фильтра в том, что если мы применим некоторые значения шума к краям вектора, например [200, 0, 10, 20, 30, 2, 50, 70, 15, 90, 100, -50]
, то результат будет примерно таким[ 0. 10. 10. 20. 20. 30. 50. 50. 70. 90. 90. 0.]
и, очевидно, это не совсем нормально для графика синуса, поскольку он будет производить те же артефакты для массива значений синуса.
Лучший подход к этой проблеме - рассматривать вектор времени как выход y
.и это значения индекса как вход x
и выполняют линейную регрессию для «линейной функции времени» , а не кавычек, это просто означает, что мы подделываем 2-мерную модельприменяя поддельный X
вектор.Код подразумевает использование функции scipy
linregress
(линейная регрессия):
from scipy.stats import linregress
l1 = [5, 0, 10, 20, 30, -20, 50, 70, 15, 90, 100]
l1_x = range(0, len(l1))
slope, intercept, r_val, p_val, std_err = linregress(l1_x, l1)
l1 = intercept + slope * l1_x
print(l1)
, чей вывод будет:
[-10.45454545 -1.63636364 7.18181818 16. 24.81818182
33.63636364 42.45454545 51.27272727 60.09090909 68.90909091
77.72727273]
Теперь давайте применим это к вашему временивектор.
import random
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import linregress
N = 20
# N = 10 # Set signal sample length
t1 = -np.pi # Simulation begins at t1
t2 = np.pi; # Simulation ends at t2
in_array = np.linspace(t1, t2, N)
# add some noise
noise_input = random.uniform(-.5, .5);
in_array[random.randint(0, len(in_array)-1)] = noise_input
# apply filter on time array
in_array_x = range(0, len(in_array))
slope, intercept, r_val, p_val, std_err = linregress(in_array_x, in_array)
in_array = intercept + slope * in_array_x
# generate sine wave
out_array = np.sin(in_array)
print("OUT ARRAY")
print(out_array)
plt.plot(in_array, out_array, color = 'red', marker = "o") ; plt.title("numpy.sin()")
plt.show()
выходной будет:
результирующий сигнал будет аппроксимацией оригинала, так какс любой формой экстраполяции / интерполяции / регрессионной фильтрации.