我正在开发一个分析数据的项目,并尝试使用最小二乘法(内置)来执行此操作。我找到了一个提供代码作为示例的教程,它工作得很好:
x = arange(0, 6e-2, 6e-2/30)
A, k, theta = 10, 1.0/3e-2, pi/6
y_true = A*sin(2*pi*k*x+theta)
y_meas = y_true+2*random.randn(len(x))
def residuals(p, y, x):
A, k, theta = p
print "A type" + str(type(A))
print "k type" + str(type(k))
print "theta type" + str(type(theta))
print "x type" + str(type(x))
err = y - A*sin(2*pi*k*x+theta)
return err
def peval(x, p):
return p[0]*sin(2*pi*p[1]*x+p[2])
p0 = [8,1/2.3e-2,pi/3]
plsq = leastsq(residuals, p0, args=(y_meas, x))
print(plsq[0])
但是,当我尝试将其转移到我自己的代码时,它不断抛出错误。我已经为此工作了一段时间,并且我认为已经成功消除了早期困扰我的所有类型不匹配问题。据我所知,目前这两段代码几乎相同,但我收到了错误 “不支持的操作数类型”并且无法弄清楚下一步该做什么。这是我的代码中与这个问题相关的部分:
if (ls is not None):
from scipy.optimize import leastsq
p0 = [8, 1/2.3e-2,pi/3]
def residuals(p, y, x):
A,k,theta = p
if (type(x) is list):
x = asarray(x)
err = y - A*sin(2*pi*k*x+theta) #Point of error
return err
def peval(x, p):
return p[0]*sin(2*pi*p[1]*x+p[2])
plsq = leastsq(residuals, p0, args=(listRelativeCount, listTime))
plsq_0 = peval(listTime, plsq[0])
其中 listTime 是在 listRelativeCount 中找到的数据的 x 值。我已经标记了代码当前失败的行。任何帮助将不胜感激,因为我已经被这个问题困扰了一个多月了。
最佳答案
在您称为#Point of error
的行中发生了三件事:您正在将值相乘、将值相加并应用sin()
函数。 “不支持的操作数类型”意味着这些操作之一出现问题。这意味着您需要验证操作数的类型,并确保您知道正在应用什么函数。
- 您确定知道所有操作数的类型(以及
dtype
,对于ndarray
),包括pi
、x
、theta
和A
? - 您确定您使用的是哪个
sin
函数吗?math.sin
与np.sin
不同,它们接受不同的操作数。 - 将列表乘以标量(如果您的
listTime
变量确实是一个列表)的效果与将标量与ndarray
相乘完全不同。
如果不清楚哪个操作导致了错误,请尝试分解表达式:
err1 = 2*pi*k
err2 = err1*x
err3 = err2 + theta
err4 = sin(err3)
err5 = A*err4
err = y - err5
这应该澄清什么操作抛出异常。
这个例子说明了为什么使用显式包名称通常是更好的主意,例如 np.sin()
而不是 sin()
。
关于python - Python 中最小二乘法的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28305678/