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

如何在Python中拟合隐函数?解决scipy.odr解包报错问题

隐函数拟合Scipy ODR报错解决

iv_function_with_series_and_shunt_resistance

这是我需要拟合的方程。在Origin中可完成拟合,但处理多组V_bias和I_out数据集时流程繁琐。我是Python新手,认为用Python实现会更高效。

我考虑使用scipy.odr或curve_fit,但这是首次接触隐函数拟合,遇到了困难。

报错代码及回溯信息

def func(var, params):
    x, y = var
    a, b, c, d = params
    return a - b * (np.exp((q *(x + y * c)) / m * kb * T) - 1) - (x + y * c) / d

Model = scipy.odr.Model(func, implicit=True)
Data = scipy.odr.Data([x,y], 1)
Odr = scipy.odr.ODR(Data, Model, [a,b,c,d], maxit=10000)
ValueError                                Traceback (most recent call last)
<ipython-input-21-c60c09e793e1> in <module>
      1 Model = scipy.odr.Model(func, implicit=True)
      2 Data = scipy.odr.Data([x,y], 1)
----> 3 Odr = scipy.odr.ODR(Data, Model, [a,b,c,d], maxit=10000,)

~\anaconda3\lib\site-packages\scipy\odr\odrpack.py in __init__(self, data, model, beta0, delta0, ifixb, ifixx, job, iprint, errfile, rptfile, ndigit, taufac, sstol, partol, maxit, stpb, stpd, sclb, scld, work, iwork)
    768         self.output = None
    769 
---> 770         self._check()
    771 
    772     def _check(self):

~\anaconda3\lib\site-packages\scipy\odr\odrpack.py in _check(self)
    829         if self.model.extra_args is not None:
    830             arglist = arglist + self.model.extra_args
---> 831         res = self.model.fcn(*arglist)
    832 
    833         if res.shape not in fcn_perms:

<ipython-input-20-bbc4658d4df0> in func(var, params)
      1 def func(var, params):
----> 2     x, y = var
      3     a, b, c, d = params
      4     return a - b * (np.exp((q *(x + y * c)) / m * kb * T) - 1) - (x + y * c) / d

ValueError: too many values to unpack (expected 2)

错误原因

scipy.odr隐式拟合模式下,传递给自定义函数的var参数是**形状为(n_vars, n_data)**的二维数组,而非两个独立的一维数组。直接执行x, y = var会尝试将二维数组拆分为两个元素,触发维度不匹配的报错。

解决方法

  1. 修正函数参数提取方式:从二维数组中按行提取x和y数据
  2. 修正指数运算优先级:原代码中指数部分的括号位置错误,会导致计算逻辑偏差
  3. 规范Data对象创建:确保输入数据为二维数组,权重参数按需设置

修正后代码示例

import scipy.odr as odr
import numpy as np

# 替换为你的实际常量值
q = 1.6e-19
m = 1.0
kb = 1.38e-23
T = 300

def func(var, params):
    # 从二维数组中提取x和y
    x = var[0]
    y = var[1]
    a, b, c, d = params
    # 修正指数部分的运算优先级
    exponent = (q * (x + y * c)) / (m * kb * T)
    return a - b * (np.exp(exponent) - 1) - (x + y * c) / d

# 替换为你的V_bias和I_out数据(一维数组)
x = np.array([...])
y = np.array([...])

Model = odr.Model(func, implicit=True)
# 将数据转为(2, N)的二维数组,权重设为None(无权重)
Data = odr.Data(np.array([x, y]), None)
# 初始参数值需根据数据合理设置
initial_params = [1.0, 1.0, 0.1, 1000.0]
Odr = odr.ODR(Data, Model, initial_params, maxit=10000)

# 运行拟合并输出结果
output = Odr.run()
output.pprint()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 14:50:33