python个人练习
panda读写Excel
读取,并装换为np.array数组方便后续操作
import pandas as pd
import numpy as np
#读取pd.read_excel('路径+文件名',sheet_name=“表单名称或序号”,skiprows=“跳过第一行”)
df = pd.read_excel('cu_pm.xlsx',sheet_name=0,skiprows=1)
data=np.array(df) #转化为np.array数组
对数组进行操作,在np.array数组上添加行:np.append(d1,data1[i:i+1,:],axis=0)
,添加列np.append(d1,data1[i:i+1,:],axis=1)
for n in range(9):
data1=data[:,2*n:2*n+2]
d1=data1[0:1,:]
for i in range(1,len(data1)):
if not(np.isnan(data1[i,0])):
if data1[i,0]==d1[-1,0]:
if data1[i,1]>d1[-1,1]:
d1[-1,1]=data1[i,1]
else:
d1=np.append(d1,data1[i:i+1,:],axis=0)
pd.DataFrame格式的数据才能写入Excel
写入的句柄: writer = pd.ExcelWriter(文件名,engine=‘openpyxl’,mode=‘a’)
engine=‘openpyxl’,mode='a’的模式下可以在原文档中操作,只要表单名称不同就不会覆盖
数据写入
d1=pd.DataFrame(d1) #将数组转化为DataFrame格式
writer = pd.ExcelWriter('cu_pm.xlsx',engine='openpyxl',mode='a')
s='S'+str(n+1)
d1.to_excel(excel_writer=writer,sheet_name=s)#数据写入
writer.save() #保存
writer.close()
matplotlib.pyplot画散点图
import matplotlib.pyplot as plt
df = pd.read_excel('cu_pm.xlsx',sheet_name='S1',skiprows=1)
data=np.array(df)
x=data[:,1]
y=data[:,2]
fig, axs = plt.subplots() #构建画布和坐标轴
axs.set_yscale('log') #坐标轴 log
axs.scatter(x,y) #画散点图
最小二乘法+梯度法拟合数据
定义函数,以及相应参数导数
def func(x,A0,A1,B0,B1,alpha,x0):
C=1+np.exp(-alpha*(x-x0))
A=A0-A1/C
B=B0-B1/C
y=A*np.exp(-B*x)
return y
#参数导数
def FDA0(x,A0,A1,B0,B1,alpha,x0):
C=1+np.exp(-alpha*(x-x0))
A=A0-A1/C
B=B0-B1/C
DA0=np.exp(-B*x)
return DA0
def FDA1(x,A0,A1,B0,B1,alpha,x0):
C=1+np.exp(-alpha*(x-x0))
A=A0-A1/C
B=B0-B1/C
DA1=np.exp(-B*x)*(-1.0/C)
return DA1
def FDB0(x,A0,A1,B0,B1,alpha,x0):
C=1+np.exp(-alpha*(x-x0))
A=A0-A1/C
B=B0-B1/C
DB0=-A*x*np.exp(-B*x)
return DB0
def FDB1(x,A0,A1,B0,B1,alpha,x0):
C=1+np.exp(-alpha*(x-x0))
A=A0-A1/C
B=B0-B1/C
DB1=-A*x*np.exp(-B*x)*(-1.0/C)
return DB1
def FDalpha(x,A0,A1,B0,B1,alpha,x0):
C=1+np.exp(-alpha*(x-x0))
A=A0-A1/C
B=B0-B1/C
Dalpha=(np.exp(-B*x)*(A1-A*B1*x)/(C**2))*np.exp(-alpha*(x-x0))*(-(x-x0))
return Dalpha
def FDx0(x,A0,A1,B0,B1,alpha,x0):
C=1+np.exp(-alpha*(x-x0))
A=A0-A1/C
B=B0-B1/C
Dx0=(np.exp(-B*x)*(A1-A*B1*x)/(C**2))*np.exp(-alpha*(x-x0))*alpha
return Dx0
最小二乘法(LeastSquare)
原数据点
(
x
i
,
y
i
)
(x_i,y_i)
(xi,yi),拟合函数
y
^
i
=
f
(
x
i
,
A
)
\hat y_i=f(x_i,A)
y^i=f(xi,A),
A
A
A代表参数集
L
S
=
∑
i
=
1
,
n
(
y
^
i
−
y
i
)
2
LS=\sum_{i=1,n}(\hat y_i-y_i)^2
LS=i=1,n∑(y^i−yi)2
L
S
LS
LS 取最小值,即:
∂
L
S
∂
A
=
2
∗
(
y
^
i
−
y
i
)
∗
∂
y
^
i
∂
A
=
0
\frac{\partial LS}{\partial A}=2*(\hat y_i-y_i)*\frac{\partial \hat y_i}{\partial A}=0
∂A∂LS=2∗(y^i−yi)∗∂A∂y^i=0
#最小二乘法
def leastSqure(x,y,y1,A0,A1,B0,B1,alpha,x0):
L=0
DA0,DA1,DB0,DB1,Dalpha,Dx0=0,0,0,0,0,0
for i in range(len(x)):
L=L+(y1[i]-y[i])**2
DA0=DA0+2*(y1[i]-y[i])*FDA0(x[i],A0,A1,B0,B1,alpha,x0)
DA1=DA1+2*(y1[i]-y[i])*FDA1(x[i],A0,A1,B0,B1,alpha,x0)
DB0=DB0+2*(y1[i]-y[i])*FDB0(x[i],A0,A1,B0,B1,alpha,x0)
DB1=DB1+2*(y1[i]-y[i])*FDB1(x[i],A0,A1,B0,B1,alpha,x0)
Dalpha=Dalpha+2*(y1[i]-y[i])*FDalpha(x[i],A0,A1,B0,B1,alpha,x0)
Dx0=Dx0+2*(y1[i]-y[i])*FDx0(x[i],A0,A1,B0,B1,alpha,x0)
return L,DA0,DA1,DB0,DB1,Dalpha,Dx0
梯度法
求出
L
S
LS
LS 对各个参数的导数,沿梯度的反向调整参数,寻找局部最低点:
Q
Q
Q为调整系数
A0=70
A1=0
B0=0.05
B1=0.02
alpha=0.05
x0=70
Q=0.01
for i in range(100):
Q=Q*0.8
y1=func(x,A0,A1,B0,B1,alpha,x0)
L,DA0,DA1,DB0,DB1,Dalpha,Dx0=leastSqure(x,y,y1,A0,A1,B0,B1,alpha,x0)
A0=A0-Q*DA0
A1=A1-Q*DA1
B0=B0-Q*DB0/10000000 #幂指数参数太敏感,调整幅度调小
B1=B1-Q*DB1/10000000
alpha=alpha-Q*Dalpha/10000000
x0=x0-Q*Dx0
if (i>0) and (abs(L0-L)<0.00001):
break
L0=L