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 函数。
最佳答案
您可以使用 def func(x, *args)
定义函数以接受可变数量的参数。然后,*args
变量包含类似 (a1, b1, a2, b2, a3, ...)
的内容。可以循环这些并对高斯求和,但我展示的是矢量化解决方案。
由于curve_fit
无法再确定此函数的参数数量,因此您可以提供一个初始猜测来确定您想要拟合的高斯数量。每个高斯函数需要两个参数,因此 [1, 1]*n
会生成正确长度的参数向量。
from scipy.optimize import curve_fit
import numpy as np
def func(x, *args):
x = x.reshape(-1, 1)
a = np.array(args[0::2]).reshape(1, -1)
b = np.array(args[1::2]).reshape(1, -1)
return np.sum(a * np.exp(-b * x), axis=1)
n = 3
xdata = np.linspace(0, 4, 50)
ydata = np.linspace(0, 4, 50)
popt, pcov = curve_fit(func, xdata, ydata, p0=[1, 1] * n)
关于python - 使用 scipy.optimize 拟合多个高斯函数的最 Pythonic 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71227196/