我对蟒蛇非常非常新,所以请忍受我,并原谅我的天真。我在Windows笔记本电脑上使用Spyder Python 2.7。正如标题所示,我有一些数据,一个理论方程式,我试图拟合我的数据,我认为是卡方拟合。我使用的理论方程是
import math
import numpy as np
import scipy.optimize as optimize
import matplotlib.pylab as plt
import csv
#with open('1.csv', 'r') as datafile:
# datareader = csv.reader(datafile)
# for row in datareader:
# print ', '.join(row)
t_y_data = np.loadtxt('exerciseball.csv', dtype=float, delimiter=',', usecols=(1,4), skiprows = 1)
print(t_y_data)
t = t_y_data[:,0]
y = t_y_data[:,1]
gamma0 = [.1]
sigma = [(0.345366)/2]*(len(t))
#len(sigma)
#print(sigma)
#print(len(sigma))
#sigma is the error in our measurements, which is the radius of the object
# Dragfunction is the theoretical equation of the position as a function of time when the thing falling experiences a drag force
# This is the function we are trying to fit to our data
# t is the independent variable time, m is the mass, and D is the Diameter
#Gamma is the value of which python will vary, until chi-squared is a minimum
def Dragfunction(x, gamma):
print x
g = 9.8
D = 0.345366
m = 0.715
# num = math.sqrt(gamma)*D*g*x
# den = math.sqrt(m*g)
# frac = num/den
# print "frac", frac
return ((m)/(gamma*D**2))*math.log(math.cosh(math.sqrt(gamma/m*g)*D*g*t))
optimize.curve_fit(Dragfunction, t, y, gamma0, sigma)
这是我收到的错误消息:
return ((m)/(gamma*D**2))*math.log(math.cosh(math.sqrt(gamma/m*g)*D*g*t))
TypeError: only length-1 arrays can be converted to Python scalars
我的教授和我花了大约三四个小时试图解决这个问题。他帮助我解决了很多问题,但我们似乎无法解决这个问题。
有人可以帮忙吗?如果您需要任何其他信息,请告诉我。
答案 0 :(得分:2)
您的错误消息来自这些math
函数只接受标量的事实,因此要调用数组上的函数,请使用numpy
版本:
In [82]: a = np.array([1,2,3])
In [83]: np.sqrt(a)
Out[83]: array([ 1. , 1.41421356, 1.73205081])
In [84]: math.sqrt(a)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
----> 1 math.sqrt(a)
TypeError: only length-1 arrays can be converted to Python scalars
在此过程中,我碰巧发现了代码中的数学错误。您在顶部的等式表示g
位于log(cosh())
内的平方根的底部,但是您已将它放在顶部,因为python中的a/b*c == a*c/b
,而不是a/(b*c)
}
log(cosh(sqrt(gamma/m*g)*D*g*t))
应该是以下任何一个:
log(cosh(sqrt(gamma/m/g)*D*g*t))
log(cosh(sqrt(gamma/(m*g))*D*g*t))
log(cosh(sqrt(gamma*g/m)*D*t)) # the simplest, by canceling with the g from outside sqrt
第二个错误是,在你的函数定义中,你有一个你从不使用的名为x
的参数,而是你正在使用t
,此时它是一个全局变量(来自你的数据),所以你不会看到错误。您不会使用curve_fit
看到效果,因为它会将t
数据传递给该函数,但如果您尝试在不同的数据集上调用Dragfunction
,它仍然会为您提供t
值的结果。可能你的意思是:
def Dragfunction(t, gamma):
print t
...
return ... D*g*t ...
其他一些注释作为未经请求的建议,因为你说你是python的新手:
您可以一次加载并“解包”t
和y
个变量:
t, y = np.loadtxt('exerciseball.csv', dtype=float, delimiter=',', usecols=(1,4), skiprows = 1, unpack=True)
如果您的错误不变,那么sigma
对curve_fit
没有任何影响,因为它只影响相对加权,因此您真的不需要它根本就没有。
以下是我的代码版本,其中包含上述所有更改。
import numpy as np
from scipy import optimize # simplified syntax
import matplotlib.pyplot as plt # pylab != pyplot
# `unpack` lets you split the columns immediately:
t, y = np.loadtxt('exerciseball.csv', dtype=float, delimiter=',',
usecols=(1, 4), skiprows=1, unpack=True)
gamma0 = .1 # does not need to be a list
def Dragfunction(x, gamma):
g = 9.8
D = 0.345366
m = 0.715
gammaD_m = gamma*D*D/m # combination is used twice, only calculate once for (small) speedup
return np.log(np.cosh(np.sqrt(gammaD_m*g)*t)) / gammaD_m
gamma_best, gamma_var = optimize.curve_fit(Dragfunction, t, y, gamma0)