基于Python与lmfit拟合不同长度多数据集的问题求助
解决方案
报错原因
你将长度不一致的多个数组转换为numpy二维数组时,numpy无法生成形状规则的二维数组,因此抛出ValueError。此外原代码还存在多处逻辑适配问题:仅保留了最后一个数据集的x、目标函数假设数据为二维数组、绘图时统一使用最后一个x等,需要整体调整以适配不同长度的数据集。
修改后的完整代码
import numpy as np import matplotlib.pyplot as plt from lmfit import minimize, Parameters, report_fit def gauss(x, amp, cen, sigma): "basic gaussian" return amp*np.exp(-(x-cen)**2/(2.*sigma**2)) def gauss_dataset(params, i, x): """calc gaussian from params for data set i using simple, hardwired naming convention""" amp = params['amp_%i' % (i+1)].value cen = params['cen_%i' % (i+1)].value sig = params['sig_%i' % (i+1)].value return gauss(x, amp, cen, sig) def objective(params, x_list, data_list): """ calculate total residual for fits to several data sets with different lengths modeled by Gaussian functions""" resid = [] # 遍历每个数据集,计算对应残差 for i in range(len(data_list)): x = x_list[i] y_data = data_list[i] y_model = gauss_dataset(params, i, x) resid.extend(y_data - y_model) # 转换为一维数组返回,满足minimize要求 return np.array(resid) # 创建5个不同长度的数据集 x_list = [] data = [] for i in np.arange(5): # 每个数据集的x长度不同 x = np.linspace(-1, 2, 151+i) amp = 0.60 + 9.50*np.random.rand() cen = -0.20 + 1.20*np.random.rand() sig = 0.25 + 0.03*np.random.rand() dat = gauss(x, amp, cen, sig) + np.random.normal(size=len(x), scale=0.1) x_list.append(x) data.append(dat) # 创建5组参数,每组对应一个数据集 fit_params = Parameters() for iy in range(5): fit_params.add(f'amp_{iy+1}', value=0.5, min=0.0, max=200) fit_params.add(f'cen_{iy+1}', value=0.4, min=-2.0, max=2.0) fit_params.add(f'sig_{iy+1}', value=0.3, min=0.01, max=3.0) # 约束所有sigma值与sig_1相等 for iy in (2, 3, 4, 5): fit_params[f'sig_{iy}'].expr = 'sig_1' # 运行全局拟合,传入x列表和数据列表 result = minimize(objective, fit_params, args=(x_list, data)) report_fit(result) # 绘制每个数据集及其拟合曲线 plt.figure() for i in range(5): x = x_list[i] y_data = data[i] y_fit = gauss_dataset(fit_params, i, x) plt.plot(x, y_data, 'o', x, y_fit, '-', label=f'Dataset {i+1}') plt.legend() plt.show()
关键修改点
- 保存每个数据集的x:用
x_list存储每个数据集对应的x数组,避免覆盖丢失。 - 放弃转换为numpy二维数组:保持
data为列表,避免形状不匹配的报错。 - 重写目标函数:遍历每个数据集,使用对应x计算残差,将所有残差拼接为一维数组返回(lmfit的
minimize要求残差是一维数组)。 - 适配拟合与绘图逻辑:拟合和绘图时,每个数据集都使用自己对应的x数组,而非统一用最后一个x。
内容的提问来源于stack exchange,提问作者Pedro Guidolim
相关产品推荐
相关产品推荐

