简体   繁体   English

我可以将一半高斯拟合到Python中的数据集吗?

[英]Can I fit half a Gaussian to a dataset in Python?

I'm trying to automatically fit a Gaussian to data, but scipy can't seem to fit data that only shows half the curve. 我正在尝试自动使高斯拟合数据,但scipy似乎无法拟合仅显示一半曲线的数据。 However, Scipy doesn't seem to be able to do this. 但是,Scipy似乎无法做到这一点。

how the right side of the Gaussian curve data looks: https://i.imgur.com/LwzN2Jd.png 高斯曲线数据右侧的外观: https : //i.imgur.com/LwzN2Jd.png

I have tried using the below code to fit curves. 我尝试使用以下代码拟合曲线。 It fits fine for fully curves. 非常适合完全弯曲。 But for half curves, it falls flat 但是对于半曲线,它会变平

''' '''

plotData = {}

#x = 0,2.5,5
#y = 16766,508,600.6

modelDataDf = df.loc[:,["x","y"]]
modelDataDf.sort_values(by=["x"],inplace=True)
modelData = modelDataDf.to_dict(orient="list")


def _1gaussian(x, amp1,cen1,sigma1):
        return amp1*(1/(sigma1*(np.sqrt(2*np.pi))))*(np.exp(-((x-cen1)**2)/((2*sigma1)**2)))

x_array = np.asarray(modelData["x"])
y_array_gauss = np.asarray(modelData["y"])
amp1 = 29000
sigma1 = 1
cen1 = -1

popt_gauss, pcov_gauss = scipy.optimize.curve_fit(_1gaussian, x_array, y_array_gauss, p0=[amp1, cen1, sigma1])
perr_gauss = np.sqrt(np.diag(pcov_gauss))

plotData["xGaussCurve"] = np.arange(0, 5.05, 0.05)
plotData["yGaussCurve"] = _1gaussian(plotData["xGaussCurve"],*popt_gauss)

''' '''

How a good fit looks: https://i.imgur.com/0gfqiRF.png 适合的外观如何: https//i.imgur.com/0gfqiRF.png

The half Gaussian it gets stuck on: https://i.imgur.com/Jsi4fzA.png 半高斯卡住了: https : //i.imgur.com/Jsi4fzA.png

blue dots show the data, bold red line shows the fit I want it to show, red dotted line is the failed fitting. 蓝色点表示数据,红色粗线表示我想要显示的拟合,红色虚线表示失败。

I get the error: 我得到错误:

RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 800. RuntimeError:找不到最佳参数:函数调用数量已达到maxfev = 800。

When trying to fit half a gaussian. 当试图拟合一半高斯时。

As commented, you won't be able to fully fit a Gaussian with only three data points -- there are as many parameters as observations. 如前所述,仅使用三个数据点就无法完全拟合高斯-参数与观测值一样多。

But if you're certain that it is "half" a Gaussian, then that implies that you know where the centroid of the Gaussian should be (perhaps at x=0 or x=-1 or something else). 但是,如果您确定它是高斯的“一半”,那么这意味着您知道高斯的质心应该在哪里(也许x = 0或x = -1或其他)。 If that is the case, you could fix the centroid and vary the amplitude and sigma of the Gaussian. 在这种情况下,您可以固定质心并改变高斯的振幅和西格玛。 Perhaps something like 也许像

from lmfit.models import GaussianModel

modelDataDf = df.loc[:,["x","y"]]
modelDataDf.sort_values(by=["x"],inplace=True)
modelData = modelDataDf.to_dict(orient="list")

x_array = np.asarray(modelData["x"])
y_array_gauss = np.asarray(modelData["y"])

model = GaussianModel()
params = model.make_params(amplitude=29000, sigma=1, center=-1)
params['center'].vary = False  # fix the centroid at -1

result = model.fit(y_array_gauss, params, x=x_array)
print(result.fit_report())

xplot = np.linspace(0, 5, 101)
yplot = result.eval(x=xplot)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM