Точка изменения наклона сигнала

Возможно, правильное обходное решение должно быть:

from bson import json_util
objects = MyDoc.objects()
json_util.dumps(objects._collection_obj.find(objects._query))
1
задан Ami 11 March 2019 в 13:47
поделиться

1 ответ

Эта проблема требует некоторых дополнительных уточнений. Основной вопрос: что вы подразумеваете под «стабильной линией»? Одно из возможных определений - «последовательные отрезки с одинаковым наклоном». Однако, поскольку наклон каждого отрезка линии, вероятно, не совсем одинаков, это может быть бесполезно.

Другое потенциальное определение - «последовательные отрезки, уклоны которых отличаются менее чем на определенное предельное значение». Всякий раз, когда мы говорим о разнице склонов, мы хотим взглянуть на вторую производную. Мы можем определить точки перехода, найдя, где абсолютное значение второй производной меньше, чем выбранное значение отсечения в каждой точке.

Тогда возникает вопрос, какое значение отсечения является приемлемым? Поскольку вам нужен метод, который классифицирует 10-ю точку как точку перехода, я буду использовать ее для принятия решения.

Вот код, который определяет предельное значение и использует его для определения точек с почти одинаковыми уклонами:

data = [-0.0006029533498891765, -0.0005180378648295125, -0.0004122940532457625, -0.0002953349889182749, -0.00018692087906219124, -0.00010093727469359659, -4.699724959278395e-05, -1.602178963390488e-05, -5.340596544722853e-07, 9.079014125876195e-06, 1.976020721514149e-05, 3.0441400304406785e-05, 3.845229512135229e-05, 4.3258832011533466e-05, 4.432695132046416e-05, 4.592913028383938e-05, 5.020160751956215e-05, 5.6076263718660146e-05, 5.9814681299896755e-05, 6.195091991774426e-05, 6.408715853560565e-05, 6.568933749899475e-05, 6.889369542577295e-05, 7.209805335256503e-05, 7.370023231594025e-05]
# Import required libraries
import numpy as np
import matplotlib.pyplot as plt

# Generate figure
plt.figure()
plt.subplot(2,1,1)
plt.title('Data')
plt.plot(data)
plt.scatter(np.arange(len(data)), data)
plt.scatter(9, data[9], c='r') # Identify 10th point

plt.subplot(2,1,2)
plt.title('First Derivative')
deriv1 = data - np.roll(data, -1) # Use simple difference to compute the derivative
deriv1 = deriv1[0:-1] # Remove the last point
plt.plot(deriv1)
plt.scatter(np.arange(len(deriv1)), deriv1)
plt.scatter(9, deriv1[9], c='r') # Identify 10th point
plt.tight_layout()

Plot of data and first derivative [1113 ]

# Approximate second derivative
deriv2 = deriv1 - np.roll(deriv1, -1) # Use simple difference to compute the derivative
deriv2 = deriv2[0:-1] # Remove the last point

# Plot data
plt.figure()
plt.subplot(2,1,1)
plt.title('Second Derivative')
x = np.arange(len(deriv2))
plt.plot(deriv2)
plt.scatter(x, deriv2)
plt.scatter(9, y[9], c='r') # Identify 10th point

plt.subplot(2,1,2)
plt.title('Absolute Value of Second Derivative')
y = np.abs(deriv2)
plt.plot(x, y)
plt.scatter(x, y)
plt.scatter(9, y[9], c='r') # Identify 10th point

# Correctly scale y axis
diff = max(y) - min(y)
scale = 0.1*diff
plt.ylim(min(y)-scale, max(y)+scale)

# Define cutoff value
cutoff = 1e-17

# Identify points where abs(deriv2) < cutoff
idx_filter = y <= cutoff
plt.axhline(y = cutoff, c='r', linestyle='--', alpha=0.5)
plt.scatter(x[idx_filter], y[idx_filter], s=200, edgecolor='r', facecolor = '')
plt.tight_layout()

Plot of second derivative and absolute value of second derivative

Оказывается, есть два отрезка с точно одинаковым наклоном. 10-й пункт определяет начало их. Следующий код находит эту точку перехода кратко и должен работать с данными только с одной такой точкой. При необходимости его можно адаптировать для поиска нескольких точек перехода.

# Compute the first derivative
deriv = data - np.roll(data, -1) # Use simple difference to compute the derivative
deriv = deriv[0:-1] # Remove the last point

# Compute the second derivative
deriv2 = deriv - np.roll(deriv, -1) # Use simple difference to compute the derivative
deriv2 = deriv2[0:-1] # Remove the last point

# Define cutoff value
cutoff = 1e-17

# Identify points where abs(deriv2) < cutoff
idx_filter = y <= cutoff
x_transition = int(x[idx_filter][0])
y_transition = data[x_transition]

print('Transition Point Index: '+str(x_transition))
print('Transition Point Value: '+str(y_transition))
print('Difference in slopes: {:.20f}'.format(deriv2[x_transition]))
>>> Transition Point Index: 9
>>> Transition Point Value: 9.079014125876195e-06
>>> Difference in slopes: 0.00000000000000000000

Так как не были предоставлены x-значения, аппроксимация производной упрощается, если предположить, что x-расстояние между каждой последовательной точкой равно 1. Добавление x-данных потребует небольших модификаций в аппроксимациях производных и другой метод аппроксимации производной может быть более подходящим, если данные распределены по оси x неравномерно.

0
ответ дан Nathaniel 11 March 2019 в 13:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: