<p>这需要非线性拟合。一个很好的工具是scipy的<code>curve_fit</code>函数。</p>
<p>要使用<code>curve_fit</code>,我们需要一个模型函数,调用它<code>func</code>,它接受<code>x</code>和我们的(猜测的)参数作为参数,并返回<code>y</code>的相应值。作为我们的模型,我们使用高斯和:</p>
<pre><code>from scipy.optimize import curve_fit
import numpy as np
def func(x, *params):
y = np.zeros_like(x)
for i in range(0, len(params), 3):
ctr = params[i]
amp = params[i+1]
wid = params[i+2]
y = y + amp * np.exp( -((x - ctr)/wid)**2)
return y
</code></pre>
<p>现在,让我们为参数创建一个初始猜测。这一猜测从振幅为60000、e折叠宽度为80的<code>x=0</code>和<code>x=1,000</code>处的峰值开始。然后,我们在<code>x=60, 140, 220, ...</code>处添加振幅为46000、宽度为25的候选峰:</p>
<pre><code>guess = [0, 60000, 80, 1000, 60000, 80]
for i in range(12):
guess += [60+80*i, 46000, 25]
</code></pre>
<p>现在,我们准备好进行调整:</p>
<pre><code>popt, pcov = curve_fit(func, x, y, p0=guess)
fit = func(x, *popt)
</code></pre>
<p>为了了解我们做得有多好,让我们绘制实际的<code>y</code>值(实心黑色曲线)和<code>fit</code>(红色虚线曲线)与<code>x</code>:</p>
<p><img src="https://i.stack.imgur.com/ZpjAA.png" alt="enter image description here"/></p>
<p>如你所见,合身性相当好。</p>
<h3>完整工作代码</h3>
<pre><code>from scipy.optimize import curve_fit
import numpy as np
import matplotlib.pyplot as plt
data = np.loadtxt('data.txt', delimiter=',')
x, y = data
plt.plot(x,y)
plt.show()
def func(x, *params):
y = np.zeros_like(x)
for i in range(0, len(params), 3):
ctr = params[i]
amp = params[i+1]
wid = params[i+2]
y = y + amp * np.exp( -((x - ctr)/wid)**2)
return y
guess = [0, 60000, 80, 1000, 60000, 80]
for i in range(12):
guess += [60+80*i, 46000, 25]
popt, pcov = curve_fit(func, x, y, p0=guess)
print popt
fit = func(x, *popt)
plt.plot(x, y)
plt.plot(x, fit , 'r-')
plt.show()
</code></pre>