我今天正在玩SciPy,我想测试最小二乘拟合。函数malo(time)在返回计算浓度时非常有效,如果我把它放在一个遍历时间步长数组的循环中(在代码“time”中)。
现在我想将我的计算浓度与我测量的浓度进行比较。我创建了一个残差函数,用于计算测量浓度(在脚本中称为conc的数组)与使用malo(时间)建模的浓度之间的差异。
使用optimize.leastsq
我希望拟合参数PD以尽可能地拟合两条曲线。我没有看到我的代码中的错误,malo(时间)表现良好,但每当我想运行optimize.leastsq
命令时,Python说“只有长度为1的数组可以转换为Python标量”。如果我将timedt数组设置为单个值,则代码运行时不会出现任何错误。
你认为有没有机会说服Python在循环中使用我的时间步长数组?
import pylab as p
import math as m
import numpy as np
from scipy import optimize
Q = 0.02114
M = 7500.0
dt = 30.0
PD = 0.020242215
tom = 26.0 #Minuten
tos = tom * 60.0 #Sekunden
timedt = np.array([30.,60.,90])
conc= np.array([ 2.7096, 2.258 , 1.3548, 0.9032, 0.9032])
def malo(time):
M1 = M/Q
M2 = 1/(tos*m.sqrt(4*m.pi*PD*((time/tos)**3)))
M3a = (1 - time/tos)**2
M3b = 4*PD*(time/tos)
M3 = m.exp(-1*(M3a/M3b))
out = M1 * M2 * M3
return out
def residuals(p,y,time):
PD = p
err = y - malo(timedt)
return err
p0 = 0.05
p1 = optimize.leastsq(residuals,p0,args=(conc,timedt))
答案 0 :(得分:3)
请注意,您正在使用NumPy模块中定义的数组。例如
timedt = np.array([30.,60.,90])
conc= np.array([ 2.7096, 2.258 , 1.3548, 0.9032, 0.9032])
现在,这些数组不是标准Python(这是一种通用语言)的一部分。问题是你正在使用math
模块中的常规操作来混合数组, 是标准Python的一部分,而且只适用于标量。
所以,例如:
M2 = 1/(tos*m.sqrt(4*m.pi*PD*((time/tos)**3)))
如果您使用np.sqrt
代替,那么将会起作用,它可用于数组:
M2 = 1/(tos*np.sqrt(4*m.pi*PD*((time/tos)**3)))
等等。
注意:SciPy和其他用于数字/科学编程的模块都知道NumPy并且是建立在它之上的,因此这些函数应该都在数组上工作。使用它们时不要使用math
。 NumPy附带了所有这些函数的副本(sqrt
,cos
,exp
,...)以使用您的数组。