You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 11:37:40