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

在Pandas中使用Lambda函数结合Lmfit拟合DataFrame数据时,如何正确访问行的x值?

在Pandas中结合Lambda和Lmfit时正确传递DataFrame行数据的问题

我来帮你梳理一下问题所在,你遇到的KeyError本质是参数传递顺序搞反了,Lmfit的minimize函数对残差函数的参数顺序有严格要求,咱们一步步来修复:

首先明确核心逻辑:minimize的第一个参数是残差函数,这个函数的第一个参数必须是Lmfit的Parameters对象,剩下的才是你要传入的自定义数据(比如DataFrame的行、拟合用的数组等)。你之前把row放在了残差函数的第一个位置,导致Lmfit把它当成参数对象处理,自然找不到row['x']这个键。


1. 调整残差函数的参数顺序

把Lmfit的参数对象放在第一位,再传入自定义数据,同时处理数据维度匹配问题:

def get_residual(params, row, W_mkin, S):
    k = 4  # Weibull parameter
    # 从Lmfit参数对象中取出具体数值
    f_mat = params['f_mat'].value
    W_mmin = params['W_mmin'].value
    x = row['x']
    
    # 将单个x值扩展为与W_mkin/S同长度的数组,避免维度不匹配报错
    x_arr = np.full_like(W_mkin, x)
    # 转换为numpy数组方便数值运算
    W_mkin_np = np.array(W_mkin)
    S_np = np.array(S)
    
    model = 1 - np.exp(-f_mat * x_arr * k * (W_mkin_np - W_mmin))
    return S_np - model

2. 修正apply中的参数传递

在lambda里调用minimize时,args只需要传入残差函数除params之外的参数,且顺序要和函数定义一致,同时修正你代码里的列名笔误(W_mkin→Wmkin):

Size_Data['parameters'] = Size_Data.apply(lambda row: minimize(get_residual, params, args=(row, row['Wmkin'], row['S'])), axis=1)

3. 完整修正后的代码

from lmfit import minimize, Parameters
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# 修正参数顺序的残差函数
def get_residual(params, row, W_mkin, S):
    k = 4  # Weibull parameter
    f_mat = params['f_mat'].value
    W_mmin = params['W_mmin'].value
    x = row['x']
    
    x_arr = np.full_like(W_mkin, x)
    W_mkin_np = np.array(W_mkin)
    S_np = np.array(S)
    
    model = 1 - np.exp(-f_mat * x_arr * k * (W_mkin_np - W_mmin))
    return S_np - model

# 定义拟合参数初始值(给一个更合理的初始值,避免拟合不收敛)
params = Parameters()
params.add('f_mat', value=0.1)
params.add('W_mmin', value=0.05)

# 构造DataFrame(修正列名笔误)
Size_Data = pd.DataFrame({
    'x': [8e-3, 4e-3],
    'Wmkin' : [[0.070247308,0.110537403, 0.150960721, 0.258617823, 0.322579856], [0.100385814, 0.200407372, 0.310034683, 0.440546697, 0.591512151, 0.794210076]],
    'S' : [[0.07053083175, 0.3514834285, 0.6014003444, 0.9091664401, 0.9980905768], [0.4077464576, 0.2298558869, 0.5899090607, 0.8002673797, 0.910358319, 0.94841536]]
})

# 应用拟合函数到每一行
Size_Data['parameters'] = Size_Data.apply(lambda row: minimize(get_residual, params, args=(row, row['Wmkin'], row['S'])), axis=1)

# 查看拟合结果示例
for idx, result in enumerate(Size_Data['parameters']):
    print(f"第{idx+1}行拟合结果:")
    print(result.params.pretty_print())

额外提示

  • 给参数设置合理初始值(比如把f_mat设为0.1而非0),能大幅提升拟合收敛概率
  • 如果拟合效果不好,可以给参数添加边界约束(比如params.add('f_mat', value=0.1, min=0)确保参数非负)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 14:33:11