curve_fit: can’t Multiply Sequence by non-int of type 'numpy.float64'

Asked

Viewed 126 times

0

I’m having trouble with the curve_fit of the scipy, the error that comes out tells me that it can’t multiply sequence by float, I’m trying to create a sequence based on the function I defined and the values found in curve_fit, but it gives me this error, I do not know what is happening, because it is exactly the same thing that has in the documentation of curve_fit, that when I run in ipython it runs well... Can anyone help? Follow the code:

import matplotlib.pyplot as plt  
import numpy as np  
from scipy.optimize import curve_fit  

X1 = [0.0,0.55,1.1,2.1,3.15,5.05,7.05,9.05,11.25]  
I1 = [397.,360.,342.,282.,249.,203.,159.,126.,102.]  

X2 = [0.0,6.2,12.01,18.21,28.51,38.91]  
I2 = [324.,292.,256.,223.,182.,153.]  

def func(x, I0, k):  
    return I0 * np.exp( -k * x )  

popt_1, pcov_1 = curve_fit(func,X1,I1)  
popt_2, pcov_2 = curve_fit(func,X2,I2)  

print popt_1, popt_2     


Y1 = func(X1, *popt_1)  
Y2 = func(X2, *popt_2)  

plt.plot(X1,Y1)  
plt.plot(X1,I1,'o')  
plt.show()  

plt.plot(X2,Y2)  
plt.plot(X2,I2,'o')  
plt.show()  

1 answer

1

The problem is that although normal Python lists and numpy "arrays" both function as sequences, and can be passed in the calls to the plt, they’re not the same thing.

In particular, one for Python’s common list, which is how you put your data into the variables X1..I2,the multiplication operator * is only set to integers, and what it does is create a new list by concatenating a list with itself n times. That is to say:

In [3]: a = [0, 1, 2]                                                                                       

In [4]: a * 3                                                                                               
Out[4]: [0, 1, 2, 0, 1, 2, 0, 1, 2]

And for this operator use, it’s easy to see that it doesn’t make sense to multiply by a decimal number (in this case, float), which you’re doing on the line return I0 * np.exp( -k * x )

For np arrays, all operators are overloaded, and are set to, in an array operation with a scalar, generate a new array performing operation on each element of the array:

In [8]: b = np.array([0, 1, 2])                                                                             

In [9]: b * 3                                                                                               
Out[9]: array([0, 3, 6])

That is, all you need to do in your code is turn your values into numpy arrays, before running the func and plot the results:

import numpy as np
...

X1 = np.array([0.0,0.55,1.1,2.1,3.15,5.05,7.05,9.05,11.25])
I1 = np.array([397.,360.,342.,282.,249.,203.,159.,126.,102.]) 

X2 = np.array([0.0,6.2,12.01,18.21,28.51,38.91])
I2 = np.array([324.,292.,256.,223.,182.,153.])
...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.