import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math
import datetime
from pandas import DataFrame,Series
from copy import deepcopy
import seaborn
def timer(func):
"""
一个装饰器,用来装饰test_data_gen()
使test_data_gen()成为一个带日期的数据
返回值为一个DataFrame
"""
def deco(*args,**kwargs):
res=func(*args,**kwargs)
date_need=[]
start_dt = datetime.datetime(2017, 1, 1)
interval = datetime.timedelta(seconds=300)
for i in range(len(res)):
date_need.append(start_dt + interval * i)
df = DataFrame(res,index = date_need[0:len(res)],columns=["data"])
return df
return deco
@timer
def test_data_gen(num_pi,num_ex,num_gap,num_bk):
"""
num_pi为要产生几个π的sin数据
num_ex为异常点的个数
num_gap为段缺失数据的个数
num_bk为单个缺失值的个数
"""
if (num_pi>0) :
num_point=72*num_pi
x=np.linspace(0,np.pi*num_pi,num_point)
signal1=[(math.sin(i)+15) for i in x] #产生测试用的num_pi个sin数据
noise=np.random.normal(0,0.05,num_point)#numpy.random.normal(噪声均值, 噪声标准差, 噪声的shape)
signal1=signal1+noise#在sin数据上添加噪声
else:
print("Please input valid num_pi")
return
if (num_ex>0) :
#随机添加异常值
point_ex=[]
for i in range(num_ex):
point_ex.append(np.random.randint(0,len(signal1))) #异常值的位置
for _ in point_ex:
signal1[_]=signal1[_]*1.8
else:
pass
if (num_gap>0) :
#随机添加段数据缺失
longth_gap=np.random.randint(15)+5 #缺口大小5~20
point_gap=[] #缺口的位置
for i in range(num_gap):
point_gap.append(np.random.randint(num_point-20))
for i in point_gap:
for j in range(longth_gap):
signal1[i+j]=None
else:
pass
if (num_bk>0) :
#随机添加单点缺失值
point_break=[]
for i in range(num_bk):
point_break.append(np.random.randint(num_point))
for _ in point_break:
signal1[_]=None
else:
pass
return signal1
@timer
def pressure_below_timer(df,standard):
"""
args为一组压力数据
standard是服务标准
返回值为低于服务标准的概率,压力数据的均值和方差
"""
args=df.iloc[:,-1]
args2=deepcopy(args)
k=0
for i in range(len(args)):
if args[i] <standard:
k+=1
else:
args2[i]=None
percent_below=k/len(args)
data_mean=np.mean(args)
data_std=np.std(args)
if(percent_below>0.1):#压力出现10%的概率不合格则认为该点压力不合格
print("压力不足,需要增压")
return args2
@timer
def standard_line(standard,args):
"""
服务基准线
"""
return [standard]*len(args)
if __name__ == '__main__':
standard=14.5 #人为设定的服务基准
df=test_data_gen(4,0,0,0)
df2=pressure_below_timer(df,standard)
df_s=standard_line(standard,df)
plt.figure(figsize=(10,5))
plt.plot(df,'b')
plt.plot(df2,'r')
plt.plot(df_s,'r')
plt.show()
由于test_data_gen()、pressure_below_timer()和standard_line()三个函数都需要添加日期数据并转换为DateFrame,为了使代码更简洁,使用装饰器装饰这三个函