利用python进行数据拟合,装饰器使用注意事项,函数传参注意事项

import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize 
import math
p=np.array([[6,4.7,48.88,5.919],
          [12,2.54,22.31,12.095],
          [13,2.29,18.95,13.002 ],
          [18,1.71,-1.65,18.118],
          [19,1.68,0.14,19.007],
          [21,1.43,-5.91,21.10],
          [24,1.28,-14.04,24.03],
          [28,1.13,-22.11,28.04],
          [30,1.10,-26.18,30.23],
          [35,0.95,-33.70,35.05],
          [36,0.95, -33.66,36.01],
          [42,0.82,-43.37,42.00],
          [49,0.67,-54.46,49.07],
          [56,0.61,-55.01,56.06],
          [63,0.52,-60.26,63.03],
          [70,0.46,-63.44,69.84],
          [72,0.46,-64.36,71.89],
          [77,0.43,-67.38,76.99],
          [84,0.40,-70.83,83.96],
          [91,0.37,-71.57,91.06],
          [96,0.34,-73.30,96.02],
          [98,0.31,-72.48,98.06],
          [105,0.31,-77.48,105.05],
          [108,0.27,-76.76,108.00],
          [112,0.24,-75.07,112.05],
          [114,0.24,-74.05,114.02],
          [119,0.21,-77.01,119.07],
          [120,0.21,-77.01,120.17],
          [126,0.18,-75.97,125.65],
          [133,0.18,-79.70,133.06],
          [140,0.15,-78.69,140.03]])
args={'p':1,'aerfa':1,'k':1,'L':2}
def VV(**kw):
    def kk(f):
        def gg(Hz,D):
            p=kw['p']
            aerfa=kw['aerfa']
            k=kw['k']
            L=kw['L']
            return f(Hz,D)
        return gg
    return kk
@VV(**args)
def V(Hz,D):
        w=2*np.pi*Hz
        a=np.sqrt(w/(2*D))
        v0=(p*aerfa)/(k*L*(a**2))
        v1=3/(2*L*a)*(np.sinh(a*L)-np.sin(a*L))/(np.cosh(a*L)+np.cos(a*L))
        v2=(1-3/(2*L*a)*(np.sinh(a*L)+np.sin(a*L))/(np.cosh(a*L)+np.cos(a*L)))
        v=v0*np.sqrt(v1**2+v2**2)
        return v
@VV(**args)
def FAI(Hz,D):
        w=2*np.pi*Hz
        a=np.sqrt(w/(2*D))
        fai1=(1-3/(2*L*a)*(np.sinh(a*L)+np.sin(a*L))/(np.cosh(a*L)+np.cos(a*L)))
        fai2= 3/(2*L*a)*(np.sinh(a*L)-np.sin(a*L))/(np.cosh(a*L)+np.cos(a*L))  
        fai=-fai1/fai2
        return np.degrees(np.arctan(fai))
def err_v(D,x,y):
    return y-V(x,D)
def err_fai(D,x,y):
    return y-FAI(x,D)
#c,rv=optimize.leastsq(err_v,1,args=(p[:,3],p[:,1]))
#c1,rv1=optimize.leastsq(err_fai,1,args=(p[:,3],p[:,2]))

以上是我用python进行数据拟合的代码,首先声明,这是一个错误的代码。由于V函数和FAI函数里面需要用到很多已知变量,而我所需拟合的未知参数只有一个,考虑到之后拟合函数optimize.leastsq的需求,我不能够将已知变量以参数的形式写在V函数和FAI函数里面,而我也不想直接将其以常数的形式直接写道函数里面,所以我就想到了python装饰器功能,将已知变量用装饰器工厂的功能以传参的形式传到函数里面去,装饰器工厂的第一层函数传入已知变量,然后返回第二层函数(也叫装饰器函数,我称之为启动函数),第二层函数传入被装饰的函数,返回第三层函数(我称之为执行函数,因为所有的实际装饰代码都是写在这个里面的),第三层函数传入被装饰函数所需的相关参数,返回被装饰的函数。我的想法是在第一层函数里面传入被装饰函数所需的已知变量,利用子函数能够使用上层函数的变量的性能来将已知变量传入到被修饰函数。但是经运行代码和各种实验发现,在执行代码里面我们能够使用第一层里面传入的参数,但是被修饰函数里面却不能够使用,经分析可能是因为被修饰函数不是在装饰器工厂里面定义的。

另一个让我花了不少时间研究的是函数的传参,在函数传参时,python有特用可变参数和可变关键字参数,所以我最开始的想法是在函数外面定义一个字典,然后将其以关键字传参**kw的形式传入装饰器工厂,我最开始认为这样传入参数后可以直接在装饰器工厂执行函数里面直接以字典的键为变量,键值为变量的值进行使用,实验发现并不能这样用,然后我又在执行函数里面对字典进行解包,代码如下

gg={'I':1,'L':2,'O':3,'V':4,'e':5,'U':6}
for i,j in gg.items():
    i=j


结果当然也失败了,经分析发现是因为key是一个变量,而kw里面的键为key所指向的值,进行赋值只能改变变量key的值,并不能将键变为变量,键值变为键的值。所以以可变关键字进行传参时,我们能以字典的形式整体将参数传进去但是得在前面加上**也能以分开的形式将一个字典拆开了在传进去(实际上**的作用就是拆分的作用)。但是在函数里面使用是只能讲kw当成一个字典进行使用。但是当函数是以正常的顺序参数进行定义时,我们却可以直接使用*P这一个参数进行传参,如下所示。

p=[1,2,3]
def gg(i,j,l):
    print(i+j+l)
gg(*p)


 以上就是我碰到的一系列问题,最后放弃了使用装饰器,而是将可变变量作为全局函数使用,最后的代码如下所示。

扫描二维码关注公众号,回复: 1951508 查看本文章
import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize 
import math
s=np.array([[6,4.7,48.88,5.919],
          [12,2.54,22.31,12.095],
          [13,2.29,18.95,13.002 ],
          [18,1.71,-1.65,18.118],
          [19,1.68,0.14,19.007],
          [21,1.43,-5.91,21.10],
          [24,1.28,-14.04,24.03],
          [28,1.13,-22.11,28.04],
          [30,1.10,-26.18,30.23],
          [35,0.95,-33.70,35.05],
          [36,0.95, -33.66,36.01],
          [42,0.82,-43.37,42.00],
          [49,0.67,-54.46,49.07],
          [56,0.61,-55.01,56.06],
          [63,0.52,-60.26,63.03],
          [70,0.46,-63.44,69.84],
          [72,0.46,-64.36,71.89],
          [77,0.43,-67.38,76.99],
          [84,0.40,-70.83,83.96],
          [91,0.37,-71.57,91.06],
          [96,0.34,-73.30,96.02],
          [98,0.31,-72.48,98.06],
          [105,0.31,-77.48,105.05],
          [108,0.27,-76.76,108.00],
          [112,0.24,-75.07,112.05],
          [114,0.24,-74.05,114.02],
          [119,0.21,-77.01,119.07],
          [120,0.21,-77.01,120.17],
          [126,0.18,-75.97,125.65],
          [133,0.18,-79.70,133.06],
          [140,0.15,-78.69,140.03]])
p=1
aerfa=1
k=1
L=2
def V(Hz,D):
        w=2*np.pi*Hz
        a=np.sqrt(w/(2*D))
        v0=(p*aerfa)/(k*L*(a**2))
        v1=3/(2*L*a)*(np.sinh(a*L)-np.sin(a*L))/(np.cosh(a*L)+np.cos(a*L))
        v2=(1-3/(2*L*a)*(np.sinh(a*L)+np.sin(a*L))/(np.cosh(a*L)+np.cos(a*L)))
        v=v0*np.sqrt(v1**2+v2**2)
        return v
def FAI(Hz,D):
        w=2*np.pi*Hz
        a=np.sqrt(w/(2*D))
        fai1=(1-3/(2*L*a)*(np.sinh(a*L)+np.sin(a*L))/(np.cosh(a*L)+np.cos(a*L)))
        fai2= 3/(2*L*a)*(np.sinh(a*L)-np.sin(a*L))/(np.cosh(a*L)+np.cos(a*L))  
        fai=-fai1/fai2
        return np.degrees(np.arctan(fai))
def err_v(D,x,y):
    return y-V(x,D)
def err_fai(D,x,y):
    return y-FAI(x,D)
c,rv=optimize.leastsq(err_v,360,args=(s[:,3],s[:,1]))
print(c,rv)
c1,rv1=optimize.leastsq(err_fai,360,args=(s[:,3],s[:,2]))
print(c1,rv1)
x=np.linspace(0,1000)
plt.plot(x,FAI(x,*c1))
plt.show()

以上仅作为自己复习使用




猜你喜欢

转载自blog.csdn.net/du_shuang/article/details/80725405
今日推荐