将理论方程拟合到我的数据

时间:2013-11-23 01:11:57

标签: python-2.7 numpy scipy spyder

我对蟒蛇非常非常新,所以请忍受我,并原谅我的天真。我在Windows笔记本电脑上使用Spyder Python 2.7。正如标题所示,我有一些数据,一个理论方程式,我试图拟合我的数据,我认为是卡方拟合。我使用的理论方程是enter image description here

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

我的教授和我花了大约三四个小时试图解决这个问题。他帮助我解决了很多问题,但我们似乎无法解决这个问题。

有人可以帮忙吗?如果您需要任何其他信息,请告诉我。

1 个答案:

答案 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的新手:

您可以一次加载并“解包”ty个变量:

t, y = np.loadtxt('exerciseball.csv', dtype=float, delimiter=',', usecols=(1,4), skiprows = 1, unpack=True)

如果您的错误不变,那么sigmacurve_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)