“只有长度为1的数组可以转换为Python标量”在Sage中使用scipy.optimize

dzjeubhm  于 2024-01-05  发布在  Python
关注(0)|答案(2)|浏览(215)

我想根据给定的数据集调整模型的参数。
我试图在Sage中使用scipy的函数curve_fit,但我一直得到
TypeError: only length-1 arrays can be converted to Python scalars
下面是我的代码:

  1. from numpy import cos,exp,pi
  2. f = lambda x: exp( - 1 / cos(x) )
  3. import numpy as np
  4. def ang(time): return (time-12)*pi/12
  5. def temp(x,maxtemp):
  6. cte=(273+maxtemp)/f(0)**(1/4)
  7. if 6<x and x<18:
  8. return float(cte*f(ang(x))**(1/4)-273)
  9. else:
  10. return -273
  11. lT=list(np.linspace(15,40,1+24*2))
  12. lT=[float(num) for num in lT] #list of y data
  13. ltimes=np.linspace(0,24,6*24+1)[1:]
  14. ltimes=list(ltimes) #list of x data
  15. u0=lT[0]
  16. def u(time,maxtemp,k): #the function I want to fit to the data
  17. def integ(t): return k*exp(k*t)*temp(t,maxtemp)
  18. return exp(-k*time)*( numerical_integral(integ, 0, time)[0] + u0 )
  19. import scipy.optimize as optimization
  20. print optimization.curve_fit(u, ltimes, lT,[1000,0.0003])

字符串

js81xvg6

js81xvg61#

scipy.optimize.curve_fit期望模型函数被 * 向量化 *:也就是说,它必须能够接收一个数组(准确地说是ndarray),并返回一个值数组。

  1. def u(time,maxtemp,k):
  2. print time % for debugging
  3. def integ(t): return k*exp(k*t)*temp(t,maxtemp)
  4. return exp(-k*time)*( numerical_integral(integ, 0, time)[0] + u0 )

字符串
print的输出将是你传递给curve_fit的整个数组ltimes。这是numerical_integral没有设计来处理的。你需要给予它一个接一个的值。
就像这样:

  1. def u(time,maxtemp,k):
  2. def integ(t): return k*exp(k*t)*temp(t,maxtemp)
  3. return [exp(-k*time_i)*( numerical_integral(integ, 0, time_i)[0] + u0) for time_i in time]


这将解决“只能转换长度为1的数组”的错误。然后你会有另一个错误,因为你的列表ltimes和lT的长度不同,这是没有意义的,因为lT应该是输入ltimes的目标输出。你应该修改这些数组的定义,以确定你想要的大小。

展开查看全部
0wi1tuuw

0wi1tuuw2#

不是这个问题的答案,但是如果你在函数中使用 math 库,它会导致这个错误,因为它们不是设计来处理数组的。所以只需要使用 numpy 函数。
举例来说:

  1. def predictor(x,a,b):
  2. return math.exp(a+b*x)

字符串
应改为:

  1. def predictor(x,a,b):
  2. return numpy.exp(a+b*x)

相关问题