2016-03-06 84 views
1

我想用python找到曲線上的拐點。曲線的數據在這裏:https://www.dropbox.com/s/rig8frgewde8i5n/fitted.txt?dl=0。請注意曲線已經適用於原始數據。原始數據可在此處獲得:https://www.dropbox.com/s/1lskykdi1ia1lu7/ww.txt?dl=0使用python修復拐點估計

import numpy as np 
# Read in array from text file 
arr = np.loadtxt(path_to_file) 

inflexion_point_1 = np.diff(arr).argmin() 
inflexion_point_2 = np.diff(arr).argmax() 

這2個拐點在附圖中以紅線顯示。但是,他們的位置似乎並不正確。第一個拐點應該靠近黑色箭頭指示的區域。我該如何解決?

enter image description here

另外,這裏是差分的曲線圖:

plt.axvline(np.gradient(arr[:365]).argmax()) 

正如你可以看到,代碼表現作爲編碼即它找到的陣列的np.diff的argmax。然而,我想找到一個接近第110天左右的位置,即大約到argmax的一半。

enter image description here

- 編輯 -

另外,這裏是表示你的原始數據的另一標繪和擬合曲線(利用二次函數)。

enter image description here

+1

我會適合你的數據的功能,並得到這個函數的導數。由於您擁有的步驟,將它直接應用於您的數據似乎會導致問題。 – Cleb

+0

感謝@Cleb,我實際上首先對數據進行了合適的處理。顯示的曲線是擬合線。將澄清這個問題。 – user308827

+1

你使用什麼底層模型來進行擬合?這對我來說看起來很明顯。你能否以這樣的方式修改你的情節,以便我們看到情節所依據的實際數據點?! – Cleb

回答

4

任何理由不直接在漸變中使用單變量樣條?

from scipy.interpolate import UnivariateSpline 

#raw data 
data = np.genfromtxt('ww.txt') 

plt.plot(np.gradient(data), '+') 

spl = UnivariateSpline(np.arange(len(data)), np.gradient(data), k=5) 
spl.set_smoothing_factor(1000) 
plt.plot(spl(np.arange(len(data))), label='Smooth Fct 1e3') 
spl.set_smoothing_factor(10000) 
plt.plot(spl(np.arange(len(data))), label='Smooth Fct 1e4') 
plt.legend(loc='lower left') 

max_idx = np.argmax(spl(np.arange(len(data)))) 
plt.vlines(max_idx, -5, 9, linewidth=5, alpha=0.3) 

enter image description here

此外,我們可以解決的最大數值:

In [122]: 

import scipy.optimize as so 
F = lambda x: -spl(x) 
so.fmin(F, 102) 
Optimization terminated successfully. 
     Current function value: -3.339112 
     Iterations: 20 
     Function evaluations: 40 
Out[122]: 
array([ 124.91303558]) 
+0

謝謝@CT朱,這有助於! – user308827