1

我对python非常非常陌生,所以请多多包涵,请原谅我的幼稚。我在我的 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

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

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

4

1 回答 1

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()),但是你把它放在顶部,因为a/b*c == a*c/b在 python 中,不是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 新手,因此还有一些其他说明作为不请自来的建议:

您可以使用以下命令一次加载和“解包” tandy变量:

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)
于 2013-11-23T02:11:49.547 回答