使用 scipy.optimize 拟合多个高斯的大多数 pythonic 方法
Most pythonic way to fit multiple gaussians using scipy.optimize
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 中拟合任意高斯分布。但是,我想准备一个函数,让用户始终使用 select 任意数量的高斯分布,并仍然尝试找到最合适的。
我正在尝试弄清楚如何修改函数 func
以便我可以向它传递一个附加参数 n=2
例如它会 return 一个函数尝试拟合 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)
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 中拟合任意高斯分布。但是,我想准备一个函数,让用户始终使用 select 任意数量的高斯分布,并仍然尝试找到最合适的。
我正在尝试弄清楚如何修改函数 func
以便我可以向它传递一个附加参数 n=2
例如它会 return 一个函数尝试拟合 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)