scipy.optimize.curve_fit,TypeError:不支持的操作数类型 [英] scipy.optimize.curve_fit, TypeError: unsupported operand type

查看:93
本文介绍了scipy.optimize.curve_fit,TypeError:不支持的操作数类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经进行了搜索,问题似乎类似于 Python scipy:不支持**或pow()的操作数类型:列表和列表
,但是此处发布的解决方案无效,我认为可能



我正在尝试使用scipy.curve_fit将数据拟合曲线,当我将所有3个参数都释放后,一切正常,并且我得到了预期的结果。

  def func(x,a,b,c):
return a * np.exp(b *( x ** c))

popt,pcov = curve_fit(func,x,y)

但是,当我尝试如下修正其中一个值(c = 2)时,

  def func2( x,a,b):
返回a * np.exp(b *(x ** 2))

popt,pcov = curve_fit(func2,x,y)

我得到 TypeError:**或pow()不支持的操作数类型: 'int'和'list'使用 nump链接问题中建议的y.power(x,2)允许代码运行,但产生错误的结果。有人看到我在做什么错吗?



编辑后添加:
甚至更令人困惑的minimumsq,据我所知,curve_fit使用的是第二个



第二次编辑:
上面提到的列表问题X和Y现在都是数组,代码运行没有错误。但是func2仍然会严重产生错误的结果。 (我会在此处发布图表,但显然我需要更多代表。)



Func 1 curvefit得到 [a,b,c] = [1.71890826 ,-0.0239123,3.17039851] ,但是对于func2,一切都出错了 [a,b] = [-2.88694423e-15,9.99999998e-01] 。我不明白这么小的更改会如何导致如此严重的问题,leastsq能够使用c = 2来拟合此数据。

解决方案

发生 TypeError 是因为将 x 传递给 func2 是一个列表。



这里是一个示例:

 将numpy导入为np 
import scipy.optimize asoptimize
def func2(x,a,b):
return a * np.exp(b *(x ** 2))

x = np.linspace(0,1,6).reshape(2,-1)
y = func2(x,1,1)
x = x.tolist()
y = y.tolist ()
print(x)
#[[0.0,0.2,0.4],[0.6000000000000001,0.8,1.0]]
print(y)
#[[1.0,1.0408107741923882 ,1.1735108709918103],[1.4333294145603404、1.8964808793049517、2.718281828459045]]

popt,pcov = optimize.curve_fit(func2,x,y)
#TypeError:不受支持的操作数类型**或pow():'list'和'int'

在这种情况下, func2 将形状(2,3)的数组 x 映射到数组 y 形状(2,3)。函数 optimize.curve_fit 期望 func2 的返回值是数字序列-而不是数组。 / p>

对我们来说幸运的是,在这种情况下, func2 x - x 的元素之间没有交互。因此,如果我们传递形状为(2,3)的数组 x 或形状为(6,)的一维数组,则实际上没有区别。



如果我们传递形状数组(6,),则 func2 将返回形状数组(6,)。完善。这样就可以了:

  x = np.asarray(x).ravel()
y = np.asarray (y).ravel()
popt,pcov = optimize.curve_fit(func2,x,y)
print(popt)
#[1. 1.]


I've done a search and the problem seems similar to Python scipy: unsupported operand type(s) for ** or pow(): 'list' and 'list' however the solution posted there did not work and I think it may actually be different.

I am trying to fit a curve to data using scipy.curve_fit, when I leave all 3 parameters free everything works correctly and I get the expected result.

def func(x,a,b,c):
  return a*np.exp(b*(x**c)) 

popt, pcov = curve_fit(func,x,y)

However when I try to fix one of the values (c=2) as below,

def func2(x,a,b):
  return a*np.exp(b*(x**2))

popt, pcov = curve_fit(func2,x,y)

I get TypeError: unsupported operand type(s) for ** or pow(): 'int' and 'list' using numpy.power(x,2) as suggested in the linked question allows the code to run but produces the wrong result. Anyone see what I'm doing wrong?

Edited to add: Even more confusingly leastsq, which as far I know is used by curve_fit, with the 2nd formula works.

2nd Edit: To those to mentioned the list problems X and Y are now both arrays and the code runs without error. However func2 still produces drastically the wrong result. (I would post the graph here but apparently I need more rep.)

Func 1 curvefit gives [a,b,c] = [ 1.71890826, -0.0239123, 3.17039851] however for func2 it all goes wrong [a,b] = [ -2.88694423e-15, 9.99999998e-01]. I don't understand how such a small change can be causing such a drastic problem, leastsq was able to fit this data with c=2.

解决方案

The TypeError occurs because the x being passed to func2 is a list.

Here is an example:

import numpy as np
import scipy.optimize as optimize
def func2(x,a,b):
    return a*np.exp(b*(x**2))

x = np.linspace(0,1,6).reshape(2,-1)
y = func2(x,1,1)
x = x.tolist()
y = y.tolist()
print(x)
# [[0.0, 0.2, 0.4], [0.6000000000000001, 0.8, 1.0]]
print(y)
# [[1.0, 1.0408107741923882, 1.1735108709918103], [1.4333294145603404, 1.8964808793049517, 2.718281828459045]]

popt, pcov = optimize.curve_fit(func2, x, y)
# TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'

In this case, func2 maps an array x of shape (2,3) to an array y of shape (2,3). The function optimize.curve_fit expects the return value from func2 to be a sequence of numbers -- not an array.

Fortunately for us, in this case, func2 is operating element-wise on each component of x -- there is no interaction between the elements of x. So it really makes no difference if we pass an array x of shape (2,3) or an 1D array of shape (6,).

If we pass an array of shape (6,) then func2 will return an array of shape (6,). Perfect. That's will do just fine:

x = np.asarray(x).ravel()
y = np.asarray(y).ravel()
popt, pcov = optimize.curve_fit(func2, x, y)
print(popt)
# [ 1.  1.]

这篇关于scipy.optimize.curve_fit,TypeError:不支持的操作数类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆