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

这是我需要拟合的方程。在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会尝试将二维数组拆分为两个元素,触发维度不匹配的报错。
解决方法
- 修正函数参数提取方式:从二维数组中按行提取x和y数据
- 修正指数运算优先级:原代码中指数部分的括号位置错误,会导致计算逻辑偏差
- 规范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
相关产品推荐
相关产品推荐

