精华内容
下载资源
问答
  • 注:本文章主要针对的是长周期时间序列数据(10000-40000条为一个周期的数据)预测 产生训练和测试数据 我们需要做的是产生周期为20000条/周期的sin函数时间序列(用于训练) 以及周期为40000条/周期的sin...

    注:本文章主要针对的是长周期的时间序列数据(10000-40000条为一个周期的数据)预测


    产生训练和测试数据

    我们需要做的是产生周期为20000条/周期的sin函数时间序列(用于训练)
    以及周期为40000条/周期的sin函数时间序列(用于测试)
    总数据长度都为200000条

    import  numpy as np
    import matplotlib.pyplot as plt
    
    x=np.arange(0,20*np.pi,2*np.pi/20000,dtype='float64')
    y=np.sin(x)
    plt.plot(y)
    plt.show()
    np.save("./train.npy",y)
    
    x=np.arange(0,10*np.pi,2*np.pi/40000,dtype='float64')
    y=np.sin(x)
    plt.plot(y)
    plt.show()
    np.save("./test.npy",y)
    

    产生的数据如图:
    训练:
    在这里插入图片描述
    测试:
    在这里插入图片描述


    进行实验

    首先我们训练模型 采用前100步去预测后1步。
    关于LSTM如何做时间序列预测的具体文章可以见简单粗暴LSTM:LSTM进行时间序列预测
    我们对于训练数据进行6次迭代之后的loss为5.1398e-04
    然后对于测试数据我们看一下预测的结果:
    (蓝色底为实际值,黄色为预测值,重合部分被覆盖)

    import  numpy as np
    import matplotlib.pyplot as plt
    
    testY = np.load("./testY"+".npy")
    y_hat = np.load("./y_hat"+".npy")
    plt.plot(testY)
    plt.plot(y_hat)
    plt.show()
    

    在这里插入图片描述
    可以看到测试数据与预测数据很贴近,也就是说对于周期为20000的数据来说,使用前100步预测后1步并不能很好地记录周期信息。
    我们交换一下,用测试数据去训练模型,用新模型去预原来的train数据,得到的结果如下:
    在这里插入图片描述
    依旧无法记录周期信息


    实验2

    本次我们采用200序列为一周期的数据去训练(模拟对于长周期数据的采样):
    在这里插入图片描述
    训练完成后,预测结果为:
    在这里插入图片描述
    将训练数据改为100/周期结果为:
    在这里插入图片描述
    改为50/周期 结果为:
    在这里插入图片描述
    可以看到LSTM对于周期数据的周期记忆并不是很好,但是如果能将周期控制在预测步数(本次为100步)之内,其高低差可以对异常检测提供思路。

    采用100/周期的数据训练,200/周期的数据进行预测,结果为:
    在这里插入图片描述
    放大:
    在这里插入图片描述
    可以看到,如果把周期控制在n_prediction(预测步数之内),当测试数据周期发生改变的时候,对于周期变化的响应体现在高低值的变化上,可以为异常检测提供思路


    实验3

    本次实验我们采用前100步去预测后100步,具体更改的是LSTM中对于数据进行整理的那一步:

    #look_back设为100
    def create_dataset(dataset, look_back):
        '''
        对数据进行处理
        '''
        dataX, dataY = [], []
        for i in range(len(dataset)-2*look_back-1):
            a = dataset[i:(i+look_back),:]
            dataX.append(a)
            dataY.append(dataset[(i+look_back):(i+2*look_back),:])
        TrainX = np.array(dataX)
        Train_Y = np.array(dataY)
        Train_Y = Train_Y.reshape(Train_Y.shape[0],Train_Y.shape[1])
        return TrainX, Train_Y
    

    同样的 使用20000/周期的数据进行训练,结果为:

    testY = np.load("./testY"+".npy")
    y_hat = np.load("./y_hat"+".npy")
    y_hat_one = []
    y_test_one = []
    #对于后100步的预测取后1步
    for i in range(len(y_hat)):
        y_hat_one.append(y_hat[i,0])
        y_test_one.append(testY[i,0])
    plt.plot(y_test_one)
    plt.plot(y_hat_one)
    plt.show()
    

    在这里插入图片描述
    得到了与实验1类似的结果

    展开全文
  • 时间序列算法分解一般是指把一个时间序列分解成:趋势序列,周期序列,残差序列。 时间序列分解算法最广为人知的可能是STL算法。它只能分解出一个周期序列。有很多博客和文章叙述了STL分解的原理,例如博客 时间...

    1.时间序列分解和STL算法

    时间序列算法分解一般是指把一个时间序列分解成:趋势序列,周期序列,残差序列。

    时间序列分解算法最广为人知的可能是STL算法。它只能分解出一个周期序列。有很多博客和文章叙述了STL分解的原理,例如博客 时间序列分解算法:STL。其中也有原论文的链接,看原论文也较容易理解。

    2.MSTL分解算法

    MSTL可以理解成multiple-STL。它和STL的区别是:STL分解的输入包含一个周期数,而这个算法可以输入多个周期数。MSTL可以分离出多个周期序列。
       STL:Y(t)=Trend(t)+Season(t)+Remainder(t)
      MSTL:Y(t)=Trend(t)+Season1(t)+Season2(t)+…+SeasonN(t)+Remainder(t)

    它的原理简述如下:
    ————————————————————————————————————
    Step0:初始化。
        原始序列设为x,空缺值用插值补全;
        将给定的所有周期数按从小到大排序,记为数组msts;
        各个周期成分seas初始值均设为0,seas可以理解成一个二维数组,第一维的长度为
        周期的个数;
        给定算法内部循环次数iterate;
        去周期成分设为deseas,初始值为原始序列deseas=x;
    Step1:对下述{}内的过程循环iterate次后停止,特别的第j次循环如下。
        {从小到大遍历周期数组msts中的周期,运行下述(1.a)~(1.d),特别的,对第i个周期
        msts[i],执行下述操作:
          (1.a)更新去周期成分:deseas=deseas+seas[i](seas[i]为第i个周期对应的序
           列,初始设为0向量);
          (1.b)对deseas用stl分解算法以第i个周期(msts[i])进行分解,分解模型记为
           fit;
          (1.c)更新第i个周期对应的周期序列为fit的周期序列,即
                     seas[i]=seasonal(fit);
          (1.d)更新去周期成分,deseas=deseas–seas[i]。
         遍历msts中的每个周期数之后,计算原序列的其他成分:
        (2.a)计算原始序列的趋势成分,trend=trendcycle(fit)。
        (3.a)计算原始序列分解的残差成分,remainder=deseas-trend。
        }
    Step2:输出原始序列的分解结果:趋势序列trend,若干周期序列seas,残差序列  
        remainder。
    ————————————————————————————————————
    可以看到:
    (1)第一次循环,从小到大遍历周期时,用STL算法把各个周期序列“剥离”出来,存到seas
       里。然后计算一个什么周期都没有trend和remainder。注意这时候deseas等于   
       trend+remainder。
    (2)第二次循环,从小到大遍历周期时,这时STL分解的是trend+reminder+seas[i],没有其
       他周期项的干扰,这时分解出第i个周期对应的周期序列应该更好。用它来更新seas[i]。
       然后再次更新trend和remainder。注意这时候deseas一直等于trend+remainder。
    (3)依次遍历,不断地优化所有的子序列。

    3.参考资料

    上述算法是从R的mstl()源码解析出来的,可能有误差,详情请参考R函数mstl()源码地址

    展开全文
  • 周期函数f(x),其周期为T,角频率为,则该函数可展开为下面三角形式的傅里叶级数(展开条件等这里略过): 二、R中forecast::fourier用法 library(forecast) y=c(1,2,3,4,1,2,3,4) y=ts(y,frequency=4) res=...

    一、傅里叶级数展开公式

    设周期函数f(x),其周期为T,则该函数可展开为下面三角形式的傅里叶级数(展开条件等这里略过):
    在这里插入图片描述

    二、R中forecast::fourier用法

    library(forecast)
    y=c(1,2,3,4,1,2,3,4)
    y=ts(y,frequency=4)
    res=fourier(y,K=2)
    

    输出结果如图:
    在这里插入图片描述

    三、fourier函数计算过程

    因为根据(公式1),时间序列中的元素可以写成下面的形式:
    在这里插入图片描述forecast::fourier()函数返回的是“非常数项”,因为把上述表格中a0,a1,a2等都去掉之后剩下的 sin项和cos项返回。返回前K对cos和sin。

    四、参考资料

    (1)百度百科-傅里叶级数展开式
    (2)R语言forecast::fourier源码

    展开全文
  • 本文详解pd.Timestamp方法创建日期时间对象、pd.Timestamp、pd.DatetimeIndex方法创建时间序列及pd.date_range创建连续时间序列、 pd.to_datetime、str和parse方法用于字符串与时间格式的相互转换、truncate方法截取...

    Pandas基于时间应用

    1 时间处理基础

    Pandas提供了四种类型的生成日期时间的对象:日期时间、时间增量、时间跨度、日期偏移量

    (1)日期时间(Date Times):具有时区支持的特定日期和时间。与Python标准库中的datetime.datetime类似。如2020年12月6日13点37分50秒;

    (2)时间增量(Time Deltas):绝对持续时间,用于在指定时间点基础上增加指定的增量,如在某年月日的基础上增加2天、增加2个月、减少4小时等,最后产生一个新的时间点;

    (3)时间跨度(Time Span):由时间点及其相关周期定义的时间跨度,如连续产生一年四个季度的时间序列;

    (4)日期偏移(Date Offsets):以日历计算的相对持续时间,表示时间间隔,两个时间点之间的长度,如日、周、月、季度、年。

    日期时间对象

    1.1 获取当前时刻的时间

    获取当前时刻的时间就是获取此时此刻与时间相关的数据,除了具体的年、月、日、时、分、秒,还会单独看年、月、周、日等指标。

    1.1.1 返回当前时刻的日期和时间

    返回当前时刻的日期和时间在Python中借助函数 now() 实现。

    from datetime import datetime
    
    datetime.now()
    
    datetime.datetime(2020, 12, 6, 14, 9, 55, 720085)
    
    datetime.date(datetime.now())   # 获取当前日期
    
    datetime.date(2020, 12, 6)
    
    datetime.time(datetime.now())   # 获取当前时间
    
    datetime.time(14, 11, 51, 776782)
    

    1.1.2 分别返回当前时刻的年、月、日

    返回当前时刻的年份在Python中借助函数 year 实现

    datetime.now().year
    
    2020
    

    返回当前时刻的月份在Python中借助函数 month 实现

    datetime.now().month
    
    11
    

    返回当前时刻的日在Excel和Python中都借助函数 day 实现

    datetime.now().day
    
    19
    

    1.1.3 返回当前时刻的周数

    与当前时刻的周相关的数据有两个,一个是当前时刻是一周中的周几,另一个是返回当前时刻所在的周在全年的周里面是第几周。

    返回当前时刻是周几在Python中借助 weekday() 函数实现。

    datetime.now().weekday()+1
    
    4
    

    Attention :Python中周几是从0开始数的,所以在后面加1

    返回当前时刻所在周的周数,在Python中使用的是 isocalendar() 函数。

    datetime.now().isocalendar()
    
    (2020, 47, 4)
    

    2020年的第47周的第4天

    datetime.now().isocalendar()[1]
    
    47
    

    1.2 pd.Timestamp创建日期时间对象

    Pandas库也提供了类似的日期时间对象 pd.Timestamp

    import pandas as pd
    pd.Timestamp("2020-12-06")
    
    Timestamp('2020-12-06 00:00:00')
    
    pd.Timestamp(2020,12,6,13,19,52)
    
    Timestamp('2020-12-06 13:19:52')
    
    pd.Timestamp(year=2020,month=12,day=6,hour=14,minute=19,second=52)  # 键值对形式指定年月日时分秒
    
    Timestamp('2020-12-06 14:19:52')
    
    pd.Timestamp(2020,12,6,13,19,52).year   # 通过year、month、day属性获取年月日
    
    2020
    

    1.4 指定日期和时间的格式

    借助 date() 函数将日期和时间设置成只展示日期。

    datetime.now().date()
    
    datetime.date(2020, 11, 19)
    

    借助 time() 函数将日期和时间设置成只展示时间。

    datetime.now().time()
    
    datetime.time(15, 1, 27, 19303)
    

    借助 strftime() 函数可以自定义时间和日期的格式,strftime() 函数是将日期和时间的格式转化为某些自定义的格式,具体的格式有以下几种

    日期转换格式

    datetime.now().strftime("%F")
    
    '2020-11-19'
    
    datetime.now().strftime("%F %H:%M:%S")
    
    '2020-11-19 15:04:31'
    

    2 时间序列

    基于时间序列的数据记录,可以通过Series、DataFrame的索引值来记录时间点,可以同步记录对应时间点的数据元素。

    2.1 指定时间点建立时间序列的Series对象

    通过 pd.Timestamp 与 pd.DatetimeIndex 方法建立指定时间序列的Series对象

    import pandas as pd
    import numpy as np
    T1 = pd.Series(np.arange(4),index=[pd.Timestamp("2020-12-6"),pd.Timestamp("2020-12-7"),pd.Timestamp("2020-12-8"),pd.Timestamp("2020-12-9")])
    print(T1)   # 指定4个时间点为索引值
    print("="*30)
    T1.index    # pandas 自动把索引归类为日期时间索引
    
    2020-12-06    0
    2020-12-07    1
    2020-12-08    2
    2020-12-09    3
    dtype: int32
    
    ==============================
    
    DatetimeIndex(['2020-12-06', '2020-12-07', '2020-12-08', '2020-12-09'], dtype='datetime64[ns]', freq=None)
    
    T1 = pd.Series(np.arange(4),index=pd.DatetimeIndex(["2020-12-6","2020-12-7","2020-12-8","2020-12-9"]))
    print(T1)   
    print("="*30)
    T1.index                                                  
    
    2020-12-06    0
    2020-12-07    1
    2020-12-08    2
    2020-12-09    3
    dtype: int32
    
    ==============================
    
    
    DatetimeIndex(['2020-12-06', '2020-12-07', '2020-12-08', '2020-12-09'], dtype='datetime64[ns]', freq=None)
    

    2.2 时间范围函数建立时间序列

    pd.date_range()函数用于产生连续的时间序列

    pd.date_range(start=None,end=None,periods=None,freq=None,tz=None,normalize=False,name=None,close=None,**kwargs)

    start :字符串或者类似datetime类型的值,可选,设置开始日期,必须与end参数搭配使用
    
    end :字符串或者类似datetime类型的值,可选,设置结束日期
    
    periods :整数,可选,设置要生成的日期周期数(也叫绝对增量),或者说在start指定开始日期的基础上,按照指定频率(freq)需要连续生成的日期数量,结合freq参数一起使用
    
    freq :字符串或者DateOffest类型值设置需要生成的日期间隔频率,默认值为"D","D"代表以Day(天)为频率,可以用数值加频率扩展频率范围,如"2D"代表以2天为一个周期频率    Attention:在以周为频率的情况下,都是从周日开始,不一定是指定的开始时间开始
    
    tz :字符串或者tzinfor值,可选,用于指定本地时区的名称
    
    normalize :默认值为False,为True时则设置开始、结束日期的时间为午夜,即零点
    
    name :字符串,默认值为None,可以设置生成DatetimeIndex对象的名称
    
    closed :可选,可选项为{None,"left","right"}可以理解为时间范围,左右边界可以设置为开闭区间,"left"表示左闭区间,"right"表示右闭区间,None表示两边都为闭区间
    
    pd.date_range(start="2020-12-6 15:02:30",end="2020-12-9 15:02:30")  # 生成2020-12-06 15:02:30至2020-12-09 15:02:30按天为间隔的连续时间序列
    
    DatetimeIndex(['2020-12-06 15:02:30', '2020-12-07 15:02:30',
                   '2020-12-08 15:02:30', '2020-12-09 15:02:30'],
                  dtype='datetime64[ns]', freq='D')
    
    pd.date_range(start="2020-12-6 15:02:30",periods=4,freq="2D",name="时间索引")  # 生成以2020-12-06 15:02:30为始的按2天为间隔的连续4个时间序列
    
    DatetimeIndex(['2020-12-06 15:02:30', '2020-12-08 15:02:30',
                   '2020-12-10 15:02:30', '2020-12-12 15:02:30'],
                  dtype='datetime64[ns]', name='时间索引', freq='2D')
    
    pd.date_range(start="2020-12-6 15:02:30",end="2020-12-9 15:02:30",closed="left")  # 生成2020-12-06 15:02:30至2020-12-09 15:02:30按天为间隔左闭右开的连续时间序列
    
    DatetimeIndex(['2020-12-06 15:02:30', '2020-12-07 15:02:30',
                   '2020-12-08 15:02:30'],
                  dtype='datetime64[ns]', freq='D')
    

    2.3 时间转换

    在不同时间场合,时间使用的要求也不一样,有需要字符串形式的,有需要datetime形式的,有日期、时间的不同组合的,因此需要灵活转换

    2.3.1 pd.to_datetime方法将字符串转为datetime型

    pd.to_datetime(arg,errors=“raise”,dayfirst=False,yearfirst=False,utc=None,box=True,format=None,exact=True,unit=None,infer_datetime_format=False,origin=“unix”,cache=False)

    arg :指定转换的数据对象,可以是整型、浮点型、字符串、列表、元组、一维数组、Serise、DataFrame和字典
    
    errors :设置出错提示方式,可选{"ignore","raise","coercec"},默认值为"raise",如果转换失败,则给出出错提示信息;"ignore"则不出发出错提示信息;"coercec"在转换过程存在无效时间值时,自动转为NaT值
    
    dayfirst :指定arg参数转换时的顺序,设置为True时,则先转换日期,再转换时间,默认值为False
    
    yearfirst :值为True时则先转换日期,默认值为False
    
    utc :值为True返回UTC DatetimeIndex,默认值为None
    
    box :默认值为True返回DatetimeIndex或相关索引对象;值为False则返回多维数组
    
    format :字符串,默认值为None,指定字符串时间转化为时间时的strftime的格式,类似strftime方法转化为时间的使用方法
    
    exact :默认值为True表示精确匹配格式,值为False则允许匹配目标字符串中的任何位置
    
    unit :字符串,默认值为"ns",对转换对象指定时间单位(D天、s秒、ma毫秒、ns纳秒)
    
    infer_datetime_format :默认值为False,如果为True,且没有给出转换固定格式(format参数),且字符串日期时间格式确定,则可以提高转换速度
    
    origin :确定日期的开始点,默认值为"unix",则日期的开始点为1970-01-01,若提供值为Timestamp日期,则以Timestamp的起点日期作为开始点日期
    
    cache :默认值为False,如果为True,则是用唯一的转换日期缓存来应用日期时间转换,解析重复的日期字符串时可以提高转换速度
    
    import pandas as pd
    from datetime import datetime
    filename = r"D:\data_test.xlsx" 
    df = pd.read_excel(filename)
    
    print(df.head())
    print("="*30)
    print(df.info())
    
      name gender   birthday start_work  income          tel            email  \
    0   赵一      男  1989/8/10 2012-09-08   15000  13611011234    zhaoyi@qq.com   
    1   王二      男  1990/10/2 2014-03-06   12500  13500012234   wanger@163.com   
    2   张三      女  1987/3/12 2009-01-08   18500  13515273330  zhangsan@qq.com   
    3   李四      女  1991/8/16 2014-06-04   13000  13923673388   lisi@gmail.com   
    4   刘五      女  1992/5/24 2014-08-10    8500  17823117890     liuwu@qq.com   
    
                       other  
    0  {教育:本科,专业:电子商务,爱好:运动}  
    1      {教育:大专,专业:汽修,爱好:}  
    2   {教育:本科,专业:数学,爱好:打篮球}  
    3   {教育:硕士,专业:统计学,爱好:唱歌}  
    4      {教育:本科,专业:美术,爱好:}  
    ==============================
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 8 entries, 0 to 7
    Data columns (total 8 columns):
     #   Column      Non-Null Count  Dtype         
    ---  ------      --------------  -----         
     0   name        8 non-null      object        
     1   gender      8 non-null      object        
     2   birthday    8 non-null      object        
     3   start_work  8 non-null      datetime64[ns]
     4   income      8 non-null      int64         
     5   tel         8 non-null      int64         
     6   email       8 non-null      object        
     7   other       8 non-null      object        
    dtypes: datetime64[ns](1), int64(2), object(5)
    memory usage: 640.0+ bytes
    None
    
    df.birthday=pd.to_datetime(df.birthday,format="%Y-%m-%d")
    df.info()
    
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 8 entries, 0 to 7
    Data columns (total 8 columns):
     #   Column      Non-Null Count  Dtype         
    ---  ------      --------------  -----         
     0   name        8 non-null      object        
     1   gender      8 non-null      object        
     2   birthday    8 non-null      datetime64[ns]
     3   start_work  8 non-null      datetime64[ns]
     4   income      8 non-null      int64         
     5   tel         8 non-null      int64         
     6   email       8 non-null      object        
     7   other       8 non-null      object        
    dtypes: datetime64[ns](2), int64(2), object(4)
    memory usage: 640.0+ bytes
    
    data = pd.DataFrame({"客户":["李","张","刘","宋"],"工资":[3500,2500,1500,500],"日期":["2020-11-19","2020-11-20","2020-12-19","2020-12-20"]},index = ["A","B","C","D"])
    print(data.info)
    
    <bound method DataFrame.info of   客户    工资          日期
    A  李  3500  2020-11-19
    B  张  2500  2020-11-20
    C  刘  1500  2020-12-19
    D  宋   500  2020-12-20>
    

    2.3.2 parse()函数将字符串格式转换为时间格式

    使用 parse() 函数将字符串格式转换为时间格式

    from dateutil.parser import parse
    time ="2020-12-06"
    print(type(time))
    print("="*30)
    print(parse(time))
    print("="*30)
    print(type(parse(time)))
    
    <class 'str'>
    ==============================
    2020-12-06 00:00:00
    ==============================
    <class 'datetime.datetime'>
    

    2.3.3 str方法将时间格式转换为字符串格式

    使用 str() 函数将时间格式转换为字符串格式

    now = str(datetime.now())
    type(now)
    
    str
    

    2.4 时间索引

    2.4.1 关键字检索

    import numpy as np 
    import pandas as pd
    index = pd.DatetimeIndex(["2020-11-19","2020-11-20","2020-12-19","2020-12-20"])
    data = pd.DataFrame(np.arange(1,5),columns= ["num"],index = index)
    data
    
    num
    2020-11-19 1
    2020-11-20 2
    2020-12-19 3
    2020-12-20 4
    data["2020"]   # 年索引
    
    num
    2020-11-19 1
    2020-11-20 2
    2020-12-19 3
    2020-12-20 4
    data["2020-11"]  # 年月索引
    
    num
    2020-11-19 1
    2020-11-20 2
    data["2020-11-19":"2020-12-20"]  # 指定时间范围索引
    
    num
    2020-11-19 1
    2020-11-20 2
    2020-12-19 3
    2020-12-20 4

    上面的索引方法适用于索引是时间的情况下,但是并不是在所有情况下,时间都可以做索引,比如说时间只是一个普通列

    from datetime import datetime
    from dateutil.parser import parse 
    index =["A","B","C","D"]
    data = pd.DataFrame({"客户":["李","张","刘","宋"],"成交时间":[parse("2020-11-19"),parse("2020-11-20"),parse("2020-12-19"),parse("2020-12-20")]},index = index)
    data
    
    客户 成交时间
    A 2020-11-19
    B 2020-11-20
    C 2020-12-19
    D 2020-12-20
    data[data["成交时间"] ==  datetime(2020,11,20)]  # 选择成交时间是2020-11-20的行
    
    客户 成交时间
    B 2020-11-20
    data[(data["成交时间"] > datetime(2020,11,19)) & (data["成交时间"] < datetime(2020,12,21))]   # 选择成交时间大于2020-11-19和成交时间小于2020-11-21的所有行
    
    客户 成交时间
    B 2020-11-20
    C 2020-12-19
    D 2020-12-20

    2.4.2 truncate方法截取时间

    通过 truncate 方法实现对Series或DataFrame对象日期的截取

    truncate(before=None,after=None,axis=None,copy=True)

    before :指定行索引值或列索引值,用于截取前面的值
    
    after :指定行索引值或列索引值,用于截取后面的值
    
    axis :0为行索引,1为列索引
    
    copy :复制数据
    
    T = pd.date_range("2020-12-6",periods=5,freq="2D")
    df1 = pd.DataFrame(("a","b","c","d","e"),index=T)
    print(df1)
    print("="*30)
    df1.truncate(before = pd.Timestamp("2020-12-07"),after= pd.Timestamp("2020-12-13"))   # 截取2020-12-07到2020-12-13这个时间段的数据
    
                0
    2020-12-06  a
    2020-12-08  b
    2020-12-10  c
    2020-12-12  d
    2020-12-14  e
    ==============================
    
    0
    2020-12-08 b
    2020-12-10 c
    2020-12-12 d

    2.5 时间增量处理

    时间增量是相对时间点上的绝对时间差异,用不同的单位表示,如天、小时、分钟、秒。可以是正数也可以是负数

    2.5.1 Timedelta()增量函数

    Timedelta 是 datetime 的一个子类,用于提供时间增量计算功能

    pd.Timedelta(value,unit,days,seconds,microseconds,milliseconds,minutes,hours,weeks)

    value :字符串、整型、Timedelta、timedelta、np.timedelta64,指定时间增量
    
    unit :字符串,可选,时间增量单位,默认值为"ns",可选值为{"Y","M","W","D","days","day","hours","hour",.....}
    
    days,seconds,microseconds,milliseconds,minutes,hours,weeks :用键值对形式显示指定增量数值
    

    (1)字符串形式增减日期、小时

    import pandas as pd
    import datetime as dt
    import numpy as np
    today = dt.datetime.now()
    print(today)
    print("="*30)
    today.date() + pd.Timedelta("2 day")   # 提供增量为两天的时间增量
    
    2020-12-08 10:24:15.549743
    ==============================
    
    datetime.date(2020, 12, 10)
    
    today + pd.Timedelta("2 hours")   # 提供增量为两小时的时间增量
    
    datetime.datetime(2020, 12, 8, 12, 24, 15, 549743)
    
    today + pd.Timedelta("-2 hours")   # 提供两小时的时间减量
    
    datetime.datetime(2020, 12, 8, 8, 24, 15, 549743)
    

    (2)以整数和时间形式提供增减量

    today + pd.Timedelta(2 ,unit="hours")   # 提供增量为两小时的时间增量
    
    datetime.datetime(2020, 12, 8, 12, 24, 15, 549743)
    
    today + pd.Timedelta(2 ,unit="W")   # 提供增量为两周的时间增量
    
    datetime.datetime(2020, 12, 22, 10, 24, 15, 549743)
    

    (3)以datetime.datetime、np.timedelta64形式提供增减量

    today + pd.Timedelta(weeks=2)    #提供增量为两周的时间增量
    
    datetime.datetime(2020, 12, 22, 10, 24, 15, 549743)
    
    today + pd.Timedelta(np.timedelta64(2,"W"))
    
    datetime.datetime(2020, 12, 22, 10, 24, 15, 549743)
    

    2.5.2 to_timedelta()转为增量函数

    pd.to_timedelta(arg,unit=“ns”,box=True,errors=“raise”)

    arg :字符串、timedelta、类似列表、Series,指定需要转换为增量的数据对象
    
    unit :增量时间单位,同pd.Timedelta的unit
    
    box :默认值为True返回Timedelta\TimedeltaIndex结果,值为False则返回timedelta64类型数据
    
    pd.to_timedelta(np.arange(5),unit="s")  # 返回连续5个秒值的时间增量
    
    TimedeltaIndex(['00:00:00', '00:00:01', '00:00:02', '00:00:03', '00:00:04'], dtype='timedelta64[ns]', freq=None)
    

    2.5.3 timedelta_range()产生连续增量函数

    timedelta_range(start=None,end=None,periods=None,freq=None,name==None,closed=None)

    start :字符串、类似timedelta对象,默认值为None,指定时间增量左边边界
    
    end :字符串、类似timedelta对象,默认值为None,指定时间增量右边边界
    
    periods :整型,默认值为None,指定周期数,即增量个数
    
    freq :字符串、DateOffest,默认值为"D",指定增量频率,可以使用倍数方式指定,如"5D"
    
    name :字符串,默认值为None,指定生成TimedeltaIndex的名称
    
    closed :字符串,默认值为None,限制左右区间值得范围,可选项为{"right","left",None}
    
    pd.timedelta_range(start="1 day",end="10 day",periods=5,name="索引")
    
    TimedeltaIndex([ '1 days 00:00:00',  '3 days 06:00:00',  '5 days 12:00:00',
                     '7 days 18:00:00', '10 days 00:00:00'],
                   dtype='timedelta64[ns]', name='索引', freq=None)
    
    pd.timedelta_range(start="1 day", periods=5,freq= "2D",name="索引")
    
    TimedeltaIndex(['1 days', '3 days', '5 days', '7 days', '9 days'], dtype='timedelta64[ns]', name='索引', freq='2D')
    

    2.5.4 时间增量属性、增量索引

    Timedelta、TimedeltaIndex对象提供了增量相关的属性,用于增量不同单位的数值的获取。当想单独获取增量的天(days)、秒(seconds)、毫秒(milliseconds)、微妙(microseconds)、纳秒(nanoseconds)值时,可以通过上述两对象所提供的属性对象进行获取。

    1、Timedelta对象

    import pandas as pd
    d1 = pd.Timedelta("31 days 10 min 20 sec")   # 建立一个Timedelta对象
    d1
    
    Timedelta('31 days 00:10:20')
    

    (1) components属性,以获取增量的所有值

    d1.components   # 显示增量的所有内容
    
    Components(days=31, hours=0, minutes=10, seconds=20, milliseconds=0, microseconds=0, nanoseconds=0)
    
    d1.components[2]  # 通过下标值,获取增量的分钟值
    
    10
    

    (2) days属性

    d1.days  # 从增量中获取天的数值
    
    31
    

    (3) seconds属性

    d1.seconds  # 从增量中获取秒的数值(分钟+秒)
    
    620
    

    (3) microseconds属性

    d1.microseconds  # 从增量中获取微秒的数值(分钟+秒)
    
    0
    

    Attention:Timedelta并没有提供hours、week等类似的其他属性,而TimedeltaIndex提供的属性也略有差异

    2、TimedeltaIndex 时间增量索引对象

    TimedeltaIndex(data,unit,freq,copy,start,periods,end,closed,name)

    data :一维数组、一维列表,可选,用于建立timedelta类似数据的索引值
    
    unit :整数、浮点数,可选,指定增量时间单位(D、h、m、s、ms、ns)
    
    freq :字符串、偏移对象,可选,指定时间频率,可以传递字符串"infer",以便在创建时将索引的频率设置为推断频率
    
    copy :可选,默认值True为复制数据,值为False为数据视图
    
    start :可选, timedelta类似类型,指定增量开始值,如果data参数为None,则用该参数指定timedelta数据的起点
    
    periods :整数,可选,指定值要求大于0,指定增量数,优先end参数设置
    
    end : timedelta类似类型,指定结東时间,可选,如果 periods为None,则生效
    
    closed :字符串或默认值None,可选,指定生成值的开闭区间范围,可选择值{"left","right", None}
    
    name :可选,指定时间增量索引的名称
    

    用 Timedeltalndex建立时间增量索引对象

    import numpy as np
    import datetime as dt
    t = pd.TimedeltaIndex(["1 days","10 days","10:20:05",np.timedelta64(10,"D"),dt.timedelta(days=10,seconds=2)])
    t
    
    TimedeltaIndex([ '1 days 00:00:00', '10 days 00:00:00',  '0 days 10:20:05',
                    '10 days 00:00:00', '10 days 00:00:02'],
                   dtype='timedelta64[ns]', freq=None)
    
    t.days
    
    Int64Index([1, 10, 0, 10, 10], dtype='int64')
    

    生成连续时间增量还可以使用 pd.timedelta_range(),方法类似 pd.date_range()

    2.6 时间周期处理

    周期表示一段范围的时间,如一天、一月、一季度、一年等,规则的时间周期用pandas中的pd Period对象表示,pd Period_range()产生连续的时间周期序列对象PeriodsIndex

    2.6.1 时间周期建立

    通过时间周期的建立,可以更加灵活地控制年、月等时间周期的变化。

    pd Period(value, freq, year,month,quarter,day,hour,minute,second)

    value : Period或 compat.string_types类型,默认值None表示时间段,如4Q2005代表2005年第四季度
    
    freq : 字符串,默认值None,指定字符串型的 Pandas时间周期。
    
    year : 整数,默认值None,指定年数
    
    month : 整数,默认值1,指定月数
    
    quarter : 整数,默认值None,指定季度数
    
    day : 整数,默认值1,指定天数。
    
    hour : 整数,默认值0,指定小时数。
    
    minute : 整数,默认值0,指定分钟数
    
    second:整数,默认值0,指定秒数。
    
    M = pd.Period("2020-12",freq="M")
    M
    
    Period('2020-12', 'M')
    
    M+2
    
    Period('2021-02', 'M')
    

    2.6.2 时间周期序列

    在需要固定时间序列的地方,可以通过 pd.period_range() 函数产生

    period_range(start=None,end= None, periods= None, freq=None,name=None)
    start : 字符串或 period对象,指定周期序列的开始时间点,默认值为None

    end : 字符串或 period对象,指定周期序列的结東时间点,默认值为None
    
    periods : 整数,指定周期个数,默认值None
    
    freq : 字符串或 Dateoffset,指定周期名称,如Y、MI、D、h、m、、ms、ns,默认值D(天)
    
    name : 字符串,默认值None,指定 Periodindex名称
    

    (1) 以月为周期产生连续的时间序列

    M = pd.period_range("2020-12-12","2021-12-12",freq="M")
    M
    
    PeriodIndex(['2020-12', '2021-01', '2021-02', '2021-03', '2021-04', '2021-05',
                 '2021-06', '2021-07', '2021-08', '2021-09', '2021-10', '2021-11',
                 '2021-12'],
                dtype='period[M]', freq='M')
    

    (2) 以季度为周期产生连续的时间序列

    Q = pd.period_range("12/12/2020","12/12/2021",freq="Q")
    Q
    
    PeriodIndex(['2020Q4', '2021Q1', '2021Q2', '2021Q3', '2021Q4'], dtype='period[Q-DEC]', freq='Q-DEC')
    
    (3)以PeriodIndex对象为基础建立二维表
    
    a=pd.DataFrame({"韦德":[25,28,23,27,26]},index=Q)
    a
    
    韦德
    2020Q4 25
    2021Q1 28
    2021Q2 23
    2021Q3 27
    2021Q4 26

    2.7 日期偏移处理

    类似时间增量,只存在细微的区别

    2.7.1 时间偏移量建立

    日期偏移量更加遵循日历持续时间规则,如 Dateoffset在增加日时总是增加到指定日的同时间,而忽略夏令时等所带来的时间差异:而 Timedelta()在增加日时,每天增加24小时

    pd.DateOffset(n,normalize,**kwds)

    n : 整数,默认值为1,指定产生偏移量数
    
    normalize : 默认值为 False,当值为True时将DateOffset添加的时间结果含入到半夜0点。
    
    kwds : 以键值对形式指定偏移量周期
    
    import pandas as pd
    t1 = pd.Timestamp("2020-12-14")
    print(t1)
    t1 + pd.DateOffset(n=2,months=3) # 增加2*3=6个月
    
    2020-12-14 00:00:00
    
    Timestamp('2021-06-14 00:00:00')
    

    2.7.2 用offsets对象附带的方法调整日期

    t2 = pd.Timestamp(2020,12,14,13,19,52)
    print(t2)
    t2 + pd.offsets.YearEnd()   # 增加到年度结束日期
    
    2020-12-14 13:19:52
    
    Timestamp('2020-12-31 13:19:52')
    
    t2 + pd.offsets.MonthBegin(n=2)  # 增加到2个月后的月初
    
    Timestamp('2021-02-01 13:19:52')
    

    2.7.3 用pd.DateOffset()函数调整日期

    t1 + pd.DateOffset(n=2,months=3)
    
    Timestamp('2021-06-14 00:00:00')
    

    2.8 时间运算

    2.8.1 计算时间差

    在Python中两个时间做差会返回一个timedelta对象,该对象中包含天数、秒、微秒三个等级,如果要获取小时、分钟,则需要进行换算。

    time_cha = datetime(2020,11,19,18,5,50)-datetime(2020,11,18,17,5,50)
    time_cha
    
    datetime.timedelta(days=1, seconds=3600)
    

    差值为1天3600秒

    time_cha.days
    
    1
    
    time_cha.seconds
    
    3600
    
    import pandas as pd
    from datetime import datetime
    filename = r"D:\data_test.xlsx" 
    df = pd.read_excel(filename)
    
    print(df.head())
    print("="*30)
    df.birthday=pd.to_datetime(df.birthday,format="%Y-%m-%d")
    df["年龄"]= datetime.now().year-df.birthday.dt.year
    print(df.head())
    
      name gender   birthday start_work  income          tel            email  \
    0   赵一      男  1989/8/10 2012-09-08   15000  13611011234    zhaoyi@qq.com   
    1   王二      男  1990/10/2 2014-03-06   12500  13500012234   wanger@163.com   
    2   张三      女  1987/3/12 2009-01-08   18500  13515273330  zhangsan@qq.com   
    3   李四      女  1991/8/16 2014-06-04   13000  13923673388   lisi@gmail.com   
    4   刘五      女  1992/5/24 2014-08-10    8500  17823117890     liuwu@qq.com   
    
                       other  
    0  {教育:本科,专业:电子商务,爱好:运动}  
    1      {教育:大专,专业:汽修,爱好:}  
    2   {教育:本科,专业:数学,爱好:打篮球}  
    3   {教育:硕士,专业:统计学,爱好:唱歌}  
    4      {教育:本科,专业:美术,爱好:}  
    ==============================
      name gender   birthday start_work  income          tel            email  \
    0   赵一      男 1989-08-10 2012-09-08   15000  13611011234    zhaoyi@qq.com   
    1   王二      男 1990-10-02 2014-03-06   12500  13500012234   wanger@163.com   
    2   张三      女 1987-03-12 2009-01-08   18500  13515273330  zhangsan@qq.com   
    3   李四      女 1991-08-16 2014-06-04   13000  13923673388   lisi@gmail.com   
    4   刘五      女 1992-05-24 2014-08-10    8500  17823117890     liuwu@qq.com   
    
                       other  年龄  
    0  {教育:本科,专业:电子商务,爱好:运动}  31  
    1      {教育:大专,专业:汽修,爱好:}  30  
    2   {教育:本科,专业:数学,爱好:打篮球}  33  
    3   {教育:硕士,专业:统计学,爱好:唱歌}  29  
    4      {教育:本科,专业:美术,爱好:}  28  
    

    2.8.2 时间偏移

    时间偏移是指给时间往前推或往后推一段时间,即加或减一段时间

    在Python中实现时间偏移的方式有两种:第一种是借助timedelta,但是它只能偏移天、秒、微秒单位的时间;第二种是用Pandas中的日期偏移量(date offset)。

    ● timedelta

    由于timedelta只支持天、秒、微秒单位的时间运算,如果是其他单位的时间运算,则需要换算成以上三种单位中的一种方可进行偏移。

    from datetime import timedelta
    data = datetime(2020,11,19,18,5,50)
    
    data + timedelta(days=1)
    
    datetime.datetime(2020, 11, 20, 18, 5, 50)
    
    data + timedelta(seconds=1)
    
    datetime.datetime(2020, 11, 19, 18, 5, 51)
    
    data - timedelta(days=1)
    
    datetime.datetime(2020, 11, 18, 18, 5, 50)
    
    data - timedelta(seconds=1)
    
    datetime.datetime(2020, 11, 19, 18, 5, 49)
    

    ● date offset

    date offset 可以直接实现天、小时、分钟单位的时间偏移,不需要换算,相比timedelta要方便一些。

    from pandas.tseries.offsets import Day,Hour,Minute
    data = datetime.now()
    data
    
    datetime.datetime(2020, 11, 19, 18, 21, 20, 937641)
    
    data + Day(1)
    
    Timestamp('2020-11-20 18:21:20.937641')
    
    data + Hour(1)
    
    Timestamp('2020-11-19 19:21:20.937641')
    
    data + Minute(10)
    
    Timestamp('2020-11-19 18:31:20.937641')
    
    data - Day(1)
    
    Timestamp('2020-11-18 18:21:20.937641')
    
    data - Hour(1)
    
    Timestamp('2020-11-19 17:21:20.937641')
    
    data - Minute(10)
    
    Timestamp('2020-11-19 18:11:20.937641')
    
    展开全文
  • 一、基于周期因子的时间序列预测 1、场景 很多数据都具有周期性,比如客流量、支付 需要确定周期长短, 比如一周,一个月,结合STL分解 观察周期变化 2、缺点 没有考虑到节假日、突发事件情况 3、STL分解介绍...
  • 时间序列的小波分析时间序列(TimeSeries)是地学研究中经常遇到的问题。在时间序列研究中,时域和频域是常用的两种基本形式。其中,时域分析具有时间定位能力,但无法得到关于时间序列变化的更多信息;频域分析(如...
  • 周期时间序列的预测

    万次阅读 2018-08-17 18:00:00
    最近在研究时间序列的时候,发现很多序列具有很强的周期性,那如何对此类序列进行预测呢? 1 数据处理 挑选一个如下图的具有周期性的时间序列。该序列是取得是过去7天的数据,每小时一个点,一共7*24个点。   2 ...
  • (关于单周期时间序列预测的论文可见这篇:陈同学在路上:时序数据预测-【论文阅读】(1)) RNN 非常适合建模动态系统,在 RNN 的隐状态中加入不确定性可进一步提高性能,因此提出了序列数据的生成模型,如(VRNN...
  • 本文通过示例学习如何发现时间序列的活动周期,如:用户什么时间段处于活动状态或有活动数据。本文给一些思路,希望对你有帮助。 1. 准备数据 为了简化,这里简单生成一些示例数据,代码如下: CREATE TABLE t_...
  • 把坑填上,用前后值的均值把缺失值补上,再看一眼: 填充好缺失值的序列.png 发现这份数据有这样几个特点,在模型设计和数据预处理的时候要考虑到: 1、这是一个周期性的时间序列,数值有规律的以天为周期上下波动...
  • 1、现有一个时间序列,具有明显的周期性,如何计算这个具体的周期值呢? 二、基于python现有方法的思路 1、基于python中SARIMAX()方法,先给出限定性的seasonal_order参数,然后使用按照aic最小的标准寻找...
  • 时间序列用户生命周期的聚类方法

    千次阅读 2015-08-05 14:11:07
    这是一篇旧文:时间序列用户生命周期的聚类方法
  • 把坑填上,用前后值的均值把缺失值补上,再看一眼:填充好缺失值的序列发现这份数据有这样几个特点,在模型设计和数据预处理的时候要考虑到:1、这是一个周期性的时间序列,数值有规律的以天为周期上下波动,图中这...
  • 论文研究-多维时间序列周期分析.pdf, 根据作者提出的能量关联度理论,探讨了多维时间序列周期分析问题,互能量关联度的计算及频率域上主要影响因素的提取,结合实例...
  • 时间序列预测综述

    2020-06-23 15:14:42
    文章目录非周期时间序列预测1. 转化为监督学习数据集,使用xgboot/LSTM模型/时间卷积网络/seq2seq(attention_based_model)2. Facebook-prophet,类似于STL分解思路3. 深度学习网络,结合CNN+RNN+Attention,作用各不...
  • 使用SPSS做时间序列预测时,如何自定义日期型数据周期/时间数据周期?问题的产生解决方案的来源:SPSS自带的语法参考DATE命令的基本使用方法两个示例讲解写好命令以后如何运行需要注意的点如果帮到了你,能留言鼓励...
  • 把坑填上,用前后值的均值把缺失值补上,再看一眼: 填充好缺失值的序列 发现这份数据有这样几个特点,在模型设计和数据预处理的时候要考虑到: 1、这是一个周期性的时间序列,数值有规律的以天为周期上下波动,图...
  • 时间序列分析 万万没想到吧,信号处理的技术,能用在数据分析中。谁叫我是学通信出生的呢? 承接上一篇:函数分解 本节承接上文找函数的周期。 文章目录时间序列分析傅里叶变换一、傅里叶变换(FFT)是什么?二、...
  • 离散时间复指数序列周期性质

    万次阅读 多人点赞 2018-07-18 23:00:42
    离散时间复指数序列的基波周期和基波频率 成谐波关系的周期离散时间复指数信号   序言 写这篇博文的目的有两个: 其一是为了下一篇博文:离散周期序列的傅里叶级数做准备,以及以后的信号处理学习打下基础。 ...
  • 论文研究-基于能量关联度的时间序列周期分析.pdf,
  • 论文研究-周期异方差时间序列中季节单位根的Gauss 检验.pdf,
  • 时间序列图以日为周期的绘制

    千次阅读 2020-02-29 23:52:31
    数据格式:x.csv date value ...class(date)是integer类型的,如何绘制横坐标是以日为周期时间序列图?下面是一种解决方法: library(tseries) library(forecase) library(zoo) library(x...
  • 时间序列分析 电子工业出版社 提 纲 1.时间序列分析概述 2.时间序列数据的预处理 3....分析时间序列图,可以从运动的角度认识事物的本质,如几个时间序列之间的差别、一个较长时间序列周期性,...
  • 参考文献用NQT方法去除时间序列的季节性周期(譬如金融、流量等时间序列以一年为周期,当时间序列样本的采样点小于一年时,如日流量、月流量等,这个季节性周期是非常明显的)。该方法的基本思路是:1、给定一组时间...
  • %z作者的Li_plot函数代码% Created by LI Xu% Version 1.0% Feburary 27, 2016% Description:% Plot precipitation% If you have any question about this code,% please do not hesitate to contact me via E-mail:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,612
精华内容 644
关键字:

周期时间序列