使用 scipy.optimize 拟合多个高斯函数的最 Pythonic 方法
from scipy.optimize import curve_fit
def func(x, a, b):
return a * np.exp(-b * x)
xdata = np.linspace(0, 4, 50)
ydata = np.linspace(0, 4, 50)
popt, pcov = curve_fit(func, xdata, ydata)
使用类似于上述方法的方法在 python 中拟合任意高斯分布是非常容易的。但是,我想准备一个函数,让用户始终选择任意数量的高斯,并仍然尝试找到最合适的。
我试图弄清楚如何修改函数 func
,以便我可以向它传递一个附加参数 n=2
例如,它会返回一个会尝试的函数并拟合 2 个高斯函数,类似于:
from scipy.optimize import curve_fit
def func2(x, a, b, d, e):
return (a * np.exp(-b * x) + c * np.exp(-d * x))
xdata = np.linspace(0, 4, 50)
ydata = np.linspace(0, 4, 50)
popt, pcov = curve_fit(func2, xdata, ydata)
无需对这些额外的情况进行硬编码,这样我们就可以传递一个函数,例如 func(...,n=2)
并获得与以下相同的结果多于。我很难找到一个优雅的解决方案来解决这个问题。我的猜测是,最好的解决方案是使用 lambda 函数。
from scipy.optimize import curve_fit
def func(x, a, b):
return a * np.exp(-b * x)
xdata = np.linspace(0, 4, 50)
ydata = np.linspace(0, 4, 50)
popt, pcov = curve_fit(func, xdata, ydata)
It is quite easy to fit an arbitrary Gaussian in python with something like the above method. However, I would like to prepare a function that always the user to select an arbitrary number of Gaussians and still attempt to find a best fit.
I'm trying to figure out how to modify the function func
so that I can pass it an additional parameter n=2
for instance and it would return a function that would try and fit 2 Gaussians, akin to:
from scipy.optimize import curve_fit
def func2(x, a, b, d, e):
return (a * np.exp(-b * x) + c * np.exp(-d * x))
xdata = np.linspace(0, 4, 50)
ydata = np.linspace(0, 4, 50)
popt, pcov = curve_fit(func2, xdata, ydata)
Without having to hard code this additional cases, so that we could instead pass a single function like func(...,n=2)
and get the same result as above. I'm having trouble finding an elegant solution to this. My guess is that the best solution will be something using a lambda
function.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用 def func(x, *args) 定义函数以接受可变数量的参数。然后,
*args
变量包含类似(a1, b1, a2, b2, a3, ...)
的内容。可以循环这些并对高斯求和,但我显示的是矢量化解决方案。由于 curve_fit 无法再确定此函数的参数数量,因此您可以提供初始猜测来确定要拟合的高斯数量。每个高斯函数需要两个参数,因此
[1, 1]*n
会生成正确长度的参数向量。You can define the function to take a variable number of arguments using
def func(x, *args)
. The*args
variable then contains something like(a1, b1, a2, b2, a3, ...)
. It would be possible to loop over those and sum the Gaussians but I'm showing a vectorized solution instead.Since
curve_fit
can no longer determine the number of parameters from this function, you can provide an initial guess that determines the amount of Gaussians you want to fit. Each Gaussian requires two parameters, so[1, 1]*n
produces a parameter vector of the correct length.