Ваши данные зашумлены, поэтому вы не можете использовать простую числовую производную. Вместо этого, как вы, возможно, уже нашли, вы должны подогнать его сплайном, а затем проверить кривизну сплайна.
Отключив этот ответ , вы можете подогнать сплайн и вычислить вторая производная (кривизна), подобная этой:
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import UnivariateSpline
x = file['n']
y = file['Ds/2']
y_spline = UnivariateSpline(x, y)
x_range = np.linspace(x[0], x[-1], 1000) # or could use x_range = x
y_spline_deriv = y_spl.derivative(n=2)
curvature = y_spline_deriv(x_range)
Тогда вы можете найти начало и конец прямой области, например, так:
straight_points = np.where(curvature.abs() <= 0.1)[0] # pick your threshold
start_idx = straight_points[0]
end_idx = straight_points[-1]
start_x = x_range[start_idx]
end_x = x_range[end_idx]
В качестве альтернативы, если вы в основном заинтересованы в найдя плоскую часть кривой (как показано на графике c), вы можете попробовать вычислить первую производную и затем найти области, где наклон находится в пределах небольшого количества минимального наклона в любом месте данные. В этом случае просто замените y_spline_deriv = y_spl.derivative(n=1)
в приведенном выше коде.