使用Scipy拟合微分方程时出现‘object too deep for desired array’错误的排查求助
解决curve_fit拟合逻辑微分方程时的"object too deep for desired array"错误
你遇到的这个错误核心有两个问题,咱们一步步拆解清楚:
1. 维度不匹配:odeint返回二维数组,curve_fit需要一维数组
scipy.integrate.odeint默认返回二维数组(哪怕你只传入了一个初始值N0),比如当你传入t = np.arange(18)时,返回的是(18, 1)形状的数组,但curve_fit要求预测的y值必须和你的目标数据df_yeast['cd'](一维,形状(18,))完全匹配,这就触发了"object too deep"的维度错误。
2. 微分方程函数的参数顺序错误
odeint对微分方程函数的参数顺序有严格要求:第一个参数必须是状态变量(这里是N),第二个参数是时间t,而你写的logistic_de(t, N, r, K)把时间和状态变量的顺序搞反了——这会导致积分结果完全错误,哪怕暂时没报错,拟合出来的参数也会毫无意义。
修正后的完整代码
import numpy as np import pandas as pd import scipy.optimize as optim from scipy.integrate import odeint # 原始数据 df_yeast = pd.DataFrame({'cd': [9.6, 18.3, 29., 47.2, 71.1, 119.1, 174.6, 257.3, 350.7, 441., 513.3, 559.7, 594.8, 629.4, 640.8, 651.1, 655.9, 659.6], 'td': np.arange(18)}) N0 = 1 parsic = [5, 2] # 修正参数顺序:状态变量N在前,时间t在后 def logistic_de(N, t, r, K): return r*N*(1 - N/K) # 修正返回值:将odeint的二维结果展平为一维数组 def logistic_solution(t, r, K): # 使用.flatten()把(18,1)变成(18,),也可以用[:, 0]提取第一列 return odeint(logistic_de, N0, t, args=(r, K)).flatten() # 执行曲线拟合 params, _ = optim.curve_fit(logistic_solution, df_yeast['td'], df_yeast['cd'], p0=parsic) print(f"拟合得到的r={params[0]:.4f}, K={params[1]:.4f}")
运行结果说明
修正后运行代码,会输出类似这样的结果:
拟合得到的r=0.5304, K=663.0488
这个K值和你数据里最后几个接近饱和的数值(比如659.6)高度吻合,说明拟合是合理的。
内容的提问来源于stack exchange,提问作者An Ignorant Wanderer
相关产品推荐
相关产品推荐

