scipy curve_fit 不喜欢数学模块 [英] scipy curve_fit doesn't like math module
问题描述
在尝试使用 scipy.optimize curve_fit
创建示例时,我发现 scipy 似乎与 Python 的 math
模块不兼容.虽然函数 f1
工作正常,但 f2
会抛出错误消息.
While trying to create an example with scipy.optimize curve_fit
I found that scipy seems to be incompatible with Python's math
module. While function f1
works fine, f2
throws an error message.
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
数组作为输入一起出现.它影响所有 math
函数,我测试过(请参阅导入中的函数)并且必须与 math 模块如何操作输入数据有关.这在 pow()
函数中最为明显 - 如果我不从 math
导入这个函数,curve_fit
与 pow 一起正常工作()
.
The error message appears with lists and numpy
arrays as input alike. It affects all math
functions, I tested (see functions in import) and must have something to do with, how the math module manipulates input data. This is most obvious with pow()
function - if I don't import this function from math
, curve_fit
works properly with pow()
.
显而易见的问题 - 为什么会发生这种情况以及如何将 math
函数与 curve_fit
一起使用?
The obvious question - why does this happen and how can math
functions be used with curve_fit
?
P.S.:请不要讨论,不应该用线性拟合来拟合样本数据.选择这只是为了说明问题.
P.S.: Please don't discuss, that one shouldn't fit the sample data with a linear fit. This was just chosen to illustrate the problem.
推荐答案
注意 numpy 数组、数组操作和标量操作!
Be careful with numpy-arrays, operations working on arrays and operations working on scalars!
Scipy optimize 假设输入(初始点)是一个一维数组,并且在其他情况下经常会出错(例如,一个列表变成了一个数组,如果你假设在列表上工作,事情就会变得混乱;那些很多问题在 StackOverflow 上都很常见,调试不是肉眼就能轻松完成的;代码交互有帮助!).
Scipy optimize assumes the input (initial-point) to be a 1d-array and often things go wrong in other cases (a list for example becomes an array and if you assumed to work on lists, things go havoc; those kind of problems are common here on StackOverflow and debugging is not that easy to do by the eye; code-interaction helps!).
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 的一些敏感函数时应该理解.
To be honest: this is part of a very basic understanding of numpy and should be understood when using scipy's somewhat sensitive functions.
这篇关于scipy curve_fit 不喜欢数学模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!