装饰器使用案例

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,为了使代码更简洁,使用装饰器装饰这三个函

猜你喜欢

转载自blog.csdn.net/elite666/article/details/81334074
今日推荐