• 时间序列的创建,差分,转换为timestamp ,从表格提取固定时间数据,以及ARIMA模型的构建和预测


    1.时间序列的创建

    1.将datetime转换为timestamp

    • pandas中,时间戳Timestamp(Series派生的子类表示)
    from datetime import datetime
    import pandas as pd
    import numpy as np
    
    • 1
    • 2
    • 3
    pd.to_datetime('20220801')
    pd.to_datetime('2022-08/01')
    pd.to_datetime('2022-08-01')
    >>Timestamp('2022-08-01 00:00:00')
    
    • 1
    • 2
    • 3
    • 4

    2.创建时间序列的Series对象

    data_index = pd.to_datetime(['2022-08-01','2022/09/01','20221001'])
    pd.Series([1,22,3],index =data_index)
    >>
    2022-08-01     1
    2022-09-01    22
    2022-10-01     3
    dtype: int64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 通过datetime列表创建
    data_index = [datetime(2011,1,2),datetime(2012,2,3),datetime(2022,8,22)]
    pd.Series(np.arange(3),index=data_index)
    >>
    2011-01-02    0
    2012-02-03    1
    2022-08-22    2
    dtype: int32
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 固定频率时间序列创建
    • data_range() 函数创建Datetimeindex对象
    • pd.date_range(
      start=None,
      end=None,
      periods=None,
      freq=None,
      tz=None,
      normalize=False,
      name=None,
      closed=None,
      **kwargs,
      )
    • start 表示开始日期
      end 表示结束日期
      periods表示产生多少个时间戳索引值
      freq表示计时单位
      至少指定其中三个参数
    c = pd.date_range(start = '2021-01-02',end = '2021-02-03',freq = 'W-SUN')
    >>DatetimeIndex(['2021-01-03', '2021-01-10', '2021-01-17', '2021-01-24',
                   '2021-01-31'],
                  dtype='datetime64[ns]', freq='W-SUN')
    # W-SUN 为每周日的日期
    
    pd.Series([1,2,3,44,55],index=c)   
    >>2021-01-03     1
    2021-01-10     2
    2021-01-17     3
    2021-01-24    44
    2021-01-31    55
    Freq: W-SUN, dtype: int64     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 偏移2周2小时为周期
    from pandas.tseries.offsets import *
    
    a = Week(2)+Hour(2)
    c = pd.date_range(start = '2021-01-02',freq = a,periods=5)
    pd.Series([1,2,3,44,55],index=c)
    >>2021-01-02 00:00:00     1
    2021-01-16 02:00:00     2
    2021-01-30 04:00:00     3
    2021-02-13 06:00:00    44
    2021-02-27 08:00:00    55
    Freq: 338H, dtype: int64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • freq相关参数别名
      在这里插入图片描述
    • 将月度数据聚合为季度
    # 把这一列作为时间索引
    data.index = pd.to_datetime(data['指标'])
    
    # 日期都算成月末
    data.index = data.index + pd.offsets.MonthEnd(0) 
    #聚合为季度
    data.iloc[:,:9].resample('Q').sum()/3
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.创建时间序列的DateFrame对象

    list_1 = [[1,2,3],[4,5,6],[11,22,33]]
    data_index = [datetime(2011,1,2),datetime(2012,2,3),datetime(2022,8,22)]
    
    • 1
    • 2

    在这里插入图片描述

    2.提取固定时间数据

    data_index = pd.to_datetime(['2022-08-01','20220901','20221001'])
    data_se = pd.Series([1,22,3],index =data_index)
    data_se
    2011-01-02     1
    2012-02-03    22
    2022-08-22     3
    dtype: int64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 取某日期的数据
    data_se['2011-01-02']
    >> 1
    
    • 1
    • 2
    • 取所有年的数据
    data_se['2011']
    >>2011-01-02    1
    dtype: int64
    
    • 1
    • 2
    • 3
    • 给所有日期进行排序(sort_index())
    data_index = pd.to_datetime(['2022-09-09','20220901','20221001'])
    data_se = pd.Series([1,22,3],index =data_index)
    data_se
    >>2022-09-09     1
    2022-09-01    22
    2022-10-01     3
    dtype: int64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    data_se = data_se.sort_index()
    >>2022-09-01    22
    2022-09-09     1
    2022-10-01     3
    dtype: int64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 取某个时间段的数据(turncate)需先排序才可使用该方法(before after)
    data_se.truncate(before='2022-09-08')
    >>2022-09-09    1
    2022-10-01    3
    dtype: int64
    
    • 1
    • 2
    • 3
    • 4

    3.时间序列的移动

    • shift(periods=1,freq=None,axis=0) 方法,用来前后移动数据,但索引不发生改变(periods 也可以为负数)
    • 向后移动 c.shift(1)
    >>原数据 --- c
    2021-01-02     1
    2021-01-16     2
    2021-01-30     3
    2021-02-13    44
    2021-02-27    55
    Freq: 2W, dtype: int64`
    >>移动后的数据 --- c.shift(1)
    2021-01-02     NaN
    2021-01-16     1.0
    2021-01-30     2.0
    2021-02-13     3.0
    2021-02-27    44.0
    Freq: 2W, dtype: float64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • c.diff(1) 一阶差分 减去前一个数据
    >>原数据 --- c
    2021-01-02     1
    2021-01-16     2
    2021-01-30     3
    2021-02-13    44
    2021-02-27    55
    Freq: 2W, dtype: int64
    
    >>移动后的数据 --- c.diff(1)
    2021-01-02     NaN
    2021-01-16     1.0
    2021-01-30     1.0
    2021-02-13    41.0
    2021-02-27    11.0
    Freq: 2W, dtype: float64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    4.ARIMA模型建立

    • 平稳性要求序列的均值和方差不发生明显的变化
    • 单位根检验主要是检验p值是否大于0.05,大于0.05的时间序列是非平稳的,需要进行差分。p值小于0.05的是平稳的时间序列,如果使用差分之后的数据进行预测,预测值也需要重新计算差分之前的值,得到真实的预测值。
    from statsmodels.tsa.stattools  import adfuller as ADF
    ADF(data['diff_1'])
    
    • 1
    • 2

    在这里插入图片描述

    • 差分 目的为了选取 d

    • 1.将一个表格(DateFrame)对象中时间的数据转换为时间序列数据

    # data['date'] 为表格中的时间列
    data = pd.read_excel(r'C:\Users\merit\Desktop\工作簿1.xlsx')
    datas = pd.to_datetime(data['date'].values,format='%Y%M%D')
    # 将该列设置为索引
    data_date = data.set_index(datas)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 2.绘制折线图查看数据分布是否平稳
    def draw_ts(timeSeries):
    
        timeSeries.plot(color='blue')
        plt.legend()
        plt.show()
    a = draw_ts(data_date['value'])
    a
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    • 3.筛选一年值的平均值(按周期重采样
    data_date['value'].resample('12M').mean()
    
    • 1
    • 4.截取所需时间日期数据(1949-1959)
    data_date = data_date["1949":"1959"]
    b = draw_ts(data_date['value'])
    b
    
    • 1
    • 2
    • 3
    • 5.差分后监测数据平稳性(目的:确定d,然后删除这俩列)
    data_date  = data_date.drop(['date'],axis=1)
    data_date['diff_1']=data_date.diff()
    draw_ts(data_date['diff_1'])
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    • 二阶差分
    data_date['diff_2']=data_date['diff_1'].diff()
    draw_ts(data_date['diff_2'])
    # 然后单位根检验(平稳即确定 d)
    from statsmodels.tsa.stattools  import adfuller as ADF
    ADF(data['diff_2'])
    # 删除这俩列
    del data_date['diff_1']
    del data_date['diff_2']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 6.确定p,q
    pmax = 5
    qmax = 5
    bic_matrix  =  []  #bic矩阵
    for  p  in  range(pmax+1):
        tmp  =  []
        for  q  in  range(qmax+1):  #存在部分报错,所以用try来跳过报错。
            try:
                tmp.append(ARIMA(data_date['value'],order=(p,2,q)).fit().bic) 
            except:
                tmp.append(None)
        bic_matrix.append(tmp)
    bic_matrix  =  pd.DataFrame(bic_matrix)  #从中可以找出最小值
    p,q  =  bic_matrix.stack().idxmin()  
    # #先用stack展平,然后用idxmin找出最小值位置。
    print(u'BIC最小的p值和q值为:%s、%s'  %(p,q))
    >> BIC最小的p值和q值为:3、5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 7.确定完p,d,q后进行arima模型建立(二阶差分后预测的数据,还需要经过计算才能得到原数据预测值。order =(p,d,q)d为差分阶数)
    from statsmodels.tsa.arima_model import ARIMA
    model = ARIMA(data, order=(3,2,5))
    result = model.fit()
    # 预测该部分日期内容
    pred = result.predict('19600101','19610101') 
    print(len(pred))
    print(pred[-13:]) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    5.完整代码建立ARIMA模型,并对后十天数据进行预测,其中预测的值为二阶差分后的值,还需进行计算来得到预测值

    import numpy as np
    import pandas as pd
    from datetime import datetime
    import matplotlib.pylab as plt
    from statsmodels.tsa.stattools import adfuller
    
    data = pd.read_excel(r'C:\Users\merit\Desktop\工作簿1.xlsx')
    data.head(5)
    data.index = data['date']
    data = data.drop(['date'],axis=1)
    
    data = data.astype({'value':'float'})
    data.dtypes
    
    from statsmodels.tsa.arima.model import ARIMA
    model = ARIMA(data, order=(1,1,1))
    result = model.fit()
    result
    
    pred = result.predict(start=1, end =len(data) + 10 ) # 从训练集第0个开始预测(start=1表示从第0个开始),预测完整个训练集后,还需要向后预测10个
    print(len(pred))
    print(pred[-10:]) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    
    
    • 1
  • 相关阅读:
    MySQL ——单行处理函数实例练习
    mtbatisplus
    No6-3.从零搭建spring-cloud-alibaba微服务框架,实现资源端用户认证与授权等(三,no6-3)
    Python程序员:代码写的好,丝滑的壁纸少不了
    使用 ProcessBuilder API 优化你的流程
    张量的连续性、contiguous函数
    swagger3+Apifox生成接口文档
    YOLO目标检测——口罩规范佩戴数据集+已标注xml和txt格式标签下载分享
    基于Java的宠物领养管理系统设计与实现(源码+lw+部署文档+讲解等)
    Vue文件中css相关知识
  • 原文地址:https://blog.csdn.net/weixin_46700209/article/details/127517637