Python scipy曲线拟合不';我不喜欢数学模块

Python scipy曲线拟合不';我不喜欢数学模块,python,python-3.x,numpy,scipy,curve-fitting,Python,Python 3.x,Numpy,Scipy,Curve Fitting,在尝试使用scipy.optimize curve\u 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.asar

在尝试使用
scipy.optimize curve\u 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
回溯(最近一次呼叫最后一次):
文件“/Documents/Programming/Eclipse/PythonDevFiles/so_test.py”,第49行,在
系数2,mat=曲线拟合(f2,x轴,y轴)
文件“/usr/local/lib/python3.5/dist packages/scipy/optimize/minpack.py”,第742行,曲线拟合
res=leastsq(func,p0,Dfun=jac,满输出=1,**kwargs)
文件“/usr/local/lib/python3.5/dist-packages/scipy/optimize/minpack.py”,第377行,在leastsq中
shape,dtype=\u check\u func('leastsq','func',func,x0,args,n)
文件“/usr/local/lib/python3.5/dist-packages/scipy/optimize/minpack.py”,第26行,在检查功能中
res=至少1d(thefunc(*(x0[:numput],)+args)))
文件“/usr/local/lib/python3.5/dist-packages/scipy/optimize/minpack.py”,第454行,func_格式
返回func(扩展数据,*参数)-ydata
文件“/Documents/Programming/Eclipse/PythonDevFiles/so_test.py”,第47行,f2
返回m*sin(x)+n
TypeError:只有长度为1的数组才能转换为Python标量
错误消息将以列表和
numpy
数组作为输入显示。它影响所有的
math
函数,我已经测试过(请参见导入中的函数),并且一定与数学模块如何处理输入数据有关。这一点在
pow()
函数中最为明显-如果我不从
math
导入此函数,
curve\u-fit
可以正确使用
pow()

一个显而易见的问题-为什么会发生这种情况,以及如何将
数学
函数与
曲线拟合
一起使用


附言:请不要讨论,我们不应该用线性拟合来拟合样本数据。选择此选项只是为了说明问题。

小心numpy数组、处理数组的操作和处理标量的操作

Scipy optimize假设输入(初始点)是1d数组,在其他情况下经常出错(例如,列表变成数组,如果您假设要处理列表,事情就会变得一团糟;这种问题在StackOverflow上很常见,调试不是很容易做到;代码交互有帮助!)


老实说:这是对numpy非常基本的理解的一部分,在使用scipy有些敏感的函数时应该理解。

感谢您的澄清,我将错误消息误读为“长度减1”。因此,
math
模块仅显式地处理离散值,而相同的numpy数学函数对数组执行此计算。我想,在引擎盖下,两者都使用相同的C库?有什么特别的原因,为什么
math
被设计成不能处理列表和数组?正如使用
pow()
函数所看到的,这似乎是
math
module specific.No。离散值是另一回事。数学模块使用标量(主要是浮点数)。Numpy的矢量化(在整个数组上工作)函数可能比使用相同C函数的for循环更高级,但这取决于函数和细节
math.sin([1,2.])
也不起作用!这是为了标量,而不是列表。numpy是一个数组/张量库,因此大多数函数都设计用于这些函数!嗯,我认为
math
库不接受列表和数组的原因,这导致了
numpy
不兼容,超出了本网站的范围(很可能是我的理解)。我会接受这个答案。@Piintesky这是一个设计决定。如果需要进行矢量化操作,则需要专门的代码,并且通常会做出一些有效的假设。核心假设是:连续内存(SIMD、BLAS、缓存等)!由于python不是在c风格数组之上构建的,因此您将为此付出高昂的代价,因为高效的矢量化操作总是在连续的内存块上工作(这适用于numpy数组;但不适用于python的列表)。(这是一个过于简单的解释和观点;只是想表达一些想法)在这种情况下,过于简单正是我的水平。再次感谢。
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