我有一个指数衰减,如x和y值的图形,在下图中标记了一个转折点。我的问题是,有无噪声,如何使用Python检测转折的区域或中间点?值在此link中给定的csv文件中。
更新:这是更清晰的图表,显示了转折点/更改点。
最佳答案
一种简单的解决方法是使用np.gradient
和阈值。
import numpy as np
from matplotlib import pyplot as plt
# generate some toy data
n = 600
t = np.linspace(0, 600, n)
y = (300 * np.exp(-0.1 * t) + 1) + 20 * (np.random.random(n))
# get the gradient
dy = np.gradient(y)
# search gradient for first occurrence of thresh value:
thresh = 0.01
idx_thresh = np.argmax(dy > thresh)
# y[idx_thresh] would be the "turning point"
# visualization
plt.plot(t, y, 'b', label='y')
plt.plot(t, dy, 'g', label='dy')
plt.plot(t[idx_thresh:], y[idx_thresh:], 'r', label=f'y[dy > {thresh}]')
plt.legend()
但是,找到阈值的位置很大程度上取决于噪声!因此,您可能需要进行一些平滑处理,例如
from scipy.signal import savgol_filter
y_filtered = savgol_filter(y, 11, 3)
dy_f = np.gradient(y_filtered)
idx_thresh = np.argmax(dy_f > thresh)
plt.plot(t, y_filtered, 'k', label='y_filtered')
plt.plot(t, dy_f, 'g', label='dy_f')
plt.plot(t[idx_thresh:], y[idx_thresh:], 'r', label=f'y[dy > {thresh}]')
plt.legend()
请注意,渐变现在更加平滑。重要提示:取决于输入数据,哪个过滤器合适!