在尝试使用scipy.optimize curve_fit创建示例时,我发现scipy似乎与Python的math模块不兼容.虽然函数f1正常运行,但f2会引发错误消息.
from scipy.optimize import curve_fit
from math import sin, pi, log, exp, floor, fabs, pow
x_axis = np.asarray([pi * i / 6 for i in range(-6, 7)])
y_axis = np.asarray([sin(i) for i in x_axis])
def f1(x, m, n):
return m * x + n
coeff1, mat = curve_fit(f1, x_axis, y_axis)
print(coeff1)
def f2(x, m, n):
return m * sin(x) + n
coeff2, mat = curve_fit(f2, x_axis, y_axis)
print(coeff2)
完整的追溯是
Traceback (most recent call last):
File "/Documents/Programming/Eclipse/PythonDevFiles/so_test.py", line 49, in <module>
coeff2, mat = curve_fit(f2, x_axis, y_axis)
File "/usr/local/lib/python3.5/dist-packages/scipy/optimize/minpack.py", line 742, in curve_fit
res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/scipy/optimize/minpack.py", line 377, in leastsq
shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
File "/usr/local/lib/python3.5/dist-packages/scipy/optimize/minpack.py", line 26, in _check_func
res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
File "/usr/local/lib/python3.5/dist-packages/scipy/optimize/minpack.py", line 454, in func_wrapped
return func(xdata, *params) - ydata
File "/Documents/Programming/Eclipse/PythonDevFiles/so_test.py", line 47, in f2
return m * sin(x) + n
TypeError: only length-1 arrays can be converted to Python scalars
出现错误消息,并带有列表和numpy数组作为输入.它会影响我测试过的所有数学函数(请参阅导入中的函数),并且必须与数学模块如何处理输入数据有关.这在pow()函数中最明显-如果我不从数学中导入该函数,curve_fit可以在pow()中正常工作.
显而易见的问题-为什么会发生这种情况,以及如何将数学函数与curve_fit一起使用?
附注:请不要讨论,不应该以线性拟合来拟合样本数据.选择它只是为了说明问题.
解决方法:
小心numpy-arrays,对数组进行操作和对标量进行操作!
Scipy Optimizer假定输入(初始点)是一维数组,在其他情况下通常会出错(例如,列表变成数组,如果您假设要处理列表,则事情会变得很混乱;这类问题是这在*上很常见,调试起来并不是一件容易的事;代码交互很有帮助!).
import numpy as np
import math
x = np.ones(1)
np.sin(x)
> array([0.84147098])
math.sin(x)
> 0.8414709848078965 # this only works as numpy has dedicated support
# as indicated by the error-msg below!
x = np.ones(2)
np.sin(x)
> array([0.84147098, 0.84147098])
math.sin(x)
> TypeError: only size-1 arrays can be converted to Python scalars
老实说:这是对numpy的非常基本的了解的一部分,在使用scipy的某些敏感函数时应该理解.