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

lmfit全局参数+子集参数拟合问题及解决:DataFrame适配

用lmfit实现分数据集拟合参数的问题解决

原始可运行代码

我有一组存储在pandas DataFrame中的数据,使用lmfit进行多方程拟合,初始可运行代码如下:

# 读取数据
df1 = pd.read_excel('Data.xlsx', skiprows=0)

# 定义拟合残差函数
def residual(params, Obvs_int, logfO2, Op_b, P, T, uncertainty):
    cS = params['a']
    cH = params['b']
    v0 = params['c']
    v1 = params['d']
    d0 = params['e']
    d1 = params['f']
    e0 = params['g']
    e1 = params['h']
    
    logK = cS + cH/T + Op_b + (v0*P + v1*P**2)/T          
    a0 = d0 + d1*Op_b
    a1 = e0 + e1*Op_b
    Calc_int = (1/(1+10**(0.25*logfO2 + logK)) - a0)/a1
    
    return (Obvs_int - Calc_int)/uncertainty

# 设置拟合参数初始值
params = Parameters()
params.add('a', value=-3)
params.add('b', value=5000)
params.add('c', value=300)
params.add('d', value=-97)
params.add('e', value=-0.13)
params.add('f', value=-0.06)
params.add('g', value=1)
params.add('h', value=1)

# 执行拟合
out1 = minimize(residual, params, args=(df1['Obvs_int'], df1['logfO2'], df1['Op_b'], df1['Pressure'], df1['Temperature'], df1['Total_unc']), nan_policy='omit')

需求

需要实现:

  • 参数cS、cH、d0、d1、e0、e1对全部数据进行拟合;
  • 参数v0、v1用于拟合其中一个数据子集;
  • 参数v2、v3用于拟合另一个数据子集。

错误尝试及问题

我在DataFrame中添加了0/1标记列p来区分子集,并用if-else编写新的残差函数:

def residual(params, Obvs_int, p, logfO2, Op_b, P, T, uncertainty):
    cS = params['a']
    cH = params['b']
    v0 = params['c']
    v1 = params['d']
    d0 = params['e']
    d1 = params['f']
    e0 = params['g']
    e1 = params['h']
    v2 = params['i']
    v3 = params['j']
    
    a0 = d0 + d1*Op_b
    a1 = e0 + e1*Op_b
    
    if p == 1:
        logK = cS + cH/T + Op_b + (v0*P + v1*P**2)/T      
        Calc_int = (1/(1+10**(0.25*logfO2 + logK)) - a0)/a1
    else:
        logK1 = cS + cH/T + Op_b + (v2*P + v3*P**2)/T      
        Calc_int = (1/(1+10**(0.25*logfO2 + logK1)) - a0)/a1
    
    return (Obvs_int - Calc_int)/uncertainty

params = Parameters()
params.add('a', value=-3)
params.add('b', value=5000)
params.add('c', value=300)
params.add('d', value=-97)
params.add('e', value=-0.13)
params.add('f', value=-0.06)
params.add('g', value=1)
params.add('h', value=1)
params.add('i', value=300)
params.add('j', value=-97)

运行后报错:'The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()',原因是将整列pandas Series传入if条件,无法直接判断布尔值,导致歧义。

解决方法及修正后代码

用np.where()替代if-else实现向量化判断,这样可以对整个Series的每个元素分别处理,避免歧义。修正后的残差函数及完整代码如下:

# 读取数据
df1 = pd.read_excel('Data.xlsx', skiprows=0)

# 定义拟合残差函数
def residual(params, Obvs_int, p, logfO2, Op_b, P, T, uncertainty):
    cS = params['a']
    cH = params['b']
    v0 = params['c']
    v1 = params['d']
    d0 = params['e']
    d1 = params['f']
    e0 = params['g']
    e1 = params['h']
    v2 = params['i']
    v3 = params['j']
    
    a0 = d0 + d1*Op_b
    a1 = e0 + e1*Op_b
    
    # 用np.where实现分数据集计算压力项
    pressure_term = np.where(p == 1, v0*P + v1*P**2, v2*P + v3*P**2)
    logK = cS + cH/T + Op_b + pressure_term/T
    Calc_int = (1/(1+10**(0.25*logfO2 + logK)) - a0)/a1
    
    return (Obvs_int - Calc_int)/uncertainty

# 设置拟合参数初始值
params = Parameters()
params.add('a', value=-3)
params.add('b', value=5000)
params.add('c', value=300)
params.add('d', value=-97)
params.add('e', value=-0.13)
params.add('f', value=-0.06)
params.add('g', value=1)
params.add('h', value=1)
params.add('i', value=300)
params.add('j', value=-97)

# 执行拟合,注意传入新增的p列参数
out1 = minimize(residual, params, args=(df1['Obvs_int'], df1['p'], df1['logfO2'], df1['Op_b'], df1['Pressure'], df1['Temperature'], df1['Total_unc']), nan_policy='omit')

内容的提问来源于stack exchange,提问作者Anme

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:01:29