美文网首页学习提升Python
Python数据分析(七):利用pandas处理时间序列数据

Python数据分析(七):利用pandas处理时间序列数据

作者: 风之舟 | 来源:发表于2019-12-28 14:58 被阅读0次

    数据分析经常会遇到带有时间序列的数据,接下来我们看一下,利用pandas如何处理这类数据。

    时间序列

    • 时间戳(timestamp)
    • 固定周期(period)
    • 时间间隔(interval)

    一、创建时间序列

    1、date_range

    • 可以指定开始时间与周期
    • H:小时
    • D:天
    • M:月

    以天(day)为单位,输出后10天的时间序列

    #TIMES #2016 Jul 1  7/1/2016    1/7/2016    2016-07-01    2016/07/01 
    #时间格式可以换成上面的
    rng = pd.date_range('2016/07/01',periods=10,freq='D')
    rng
    

    也可以3天为单位,输出后10个序列

    rng = pd.date_range('2016/07/01',periods=10,freq='3D')
    rng
    

    或者指定起始时间

    rng = pd.date_range(start = '2016/07/01',end = '2016/07/10',freq='D')
    rng
    

    生成Series序列

    time = pd.Series(np.random.randn(20),index=pd.date_range(dt.datetime(2016,1,1),periods=20))
    time
    

    2、truncate过滤

    time.truncate(before='2016-1-10')#过滤掉2016-1-10之前的数据
    
    time.truncate(after='2016-1-10')#过滤掉之后的
    

    提取数据

    print(time['2016-01-15'])
    
    print(time['2016-01-15':'2016-01-20'])#切片的方式
    
    data = pd.date_range('2010-01-01','2011-01-01',freq='M')
    data
    

    参数freq中可以选的数值:


    3、时间戳

    pd.Timestamp('2016-07-10')
    
    #可以指定更多细节
    pd.Timestamp('2016-07-10 10')
    
    pd.Timestamp('2016-07-10 10:15')
    

    4、时间区间

    pd.Period('2016-01')
    
    pd.Period('2016-01-01')
    

    5、时间加减

    • TIME OFFSETS

    产生一个一天的时间偏移量

    #产生一个一天的时间偏移量
    pd.Timedelta('1 day')
    
    #得到2016-01-01 10:10的后一天时刻:
    pd.Period('2016-01-01 10:10') + pd.Timedelta('1 day')
    
    #时间戳加减:
    pd.Timestamp('2016-01-01 10:10') + pd.Timedelta('1 day')
    
    #加15ns
    pd.Timestamp('2016-01-01 10:10') + pd.Timedelta('15 ns')
    

    在时间间隔freq参数中,我们既可以写成25H,也可以写成1D1H这种通俗的表达:

    pd.period_range('2016-01-01 10:10',freq='25H',periods=10)
    
    pd.period_range('2016-01-01 10:10',freq='1D1H',periods=10)
    

    6、指定索引

    rng = pd.date_range('2016 Jul 1',periods=10,freq='D')
    pd.Series(range(len(rng)),index=rng)
    
    #构造任意的Series结构时间序列数据:
    periods=[pd.Period('2016-01'),pd.Period('2016-02'),pd.Period('2016-03')]
    ts = pd.Series(np.random.randn(len(periods)),index=periods)
    ts
    
    type(ts.index)
    

    7、时间戳和时间周期可以转换

    #产生时间周期
    ts = pd.Series(range(10),pd.date_range('07-10-16 8:00',periods=10,freq='H'))
    ts
    
    #将时间周期转化为时间戳
    ts_period = ts.to_period()
    ts_period
    

    8、时间周期和时间戳的区别

    • 对时间周期的切片操作
    ts_period['2016-07-10 08:30':'2016-07-10 11:45']
    
    • 对时间戳的切片操作
    ts['2016-07-10 08:30':'2016-07-10 11:45']
    

    二、数据重采样

    • 时间数据由一个频率转换到另一个频率
    • 降采样:例如将365天数据变为12个月的数据
    • 升采样:相反
    #从1/1/2011开始,时间间隔为1天,产生90个时间数据
    rng = pd.date_range('1/1/2011',periods=90,freq='D')
    ts = pd.Series(np.random.randn(len(rng)),index=rng)
    ts.head()
    

    1、降采样

    #将以上数据降采样为月数据,观察每个月数据之和、
    ts.resample('M').sum()
    
    #降采样为3天,并求和
    ts.resample('3D').sum()
    

    计算降采样后数据均值

    #计算降采样后数据均值
    day3Ts=ts.resample('3D').mean()
    day3Ts
    

    2、升采样

    直接升采样是有问题的,因为有数据缺失

    #
    day3Ts.resample('D').asfreq()
    

    使用插值的方法

    • ffill 空值取前面的值
    • bfill 空值取后面的值
    • interpolate 线性取值
    day3Ts.resample('D').ffill(1)#一个值填充
    
    day3Ts.resample('D').ffill(2)#两个值填充
    

    全部空值填充

    day3Ts.resample('D').ffill()
    
    day3Ts.resample('D').bfill(1)
    
    day3Ts.resample('D').bfill(2)
    
    day3Ts.resample('D').bfill()
    

    使用interpolate线性取值

    # 使用interpolate线性取值
    day3Ts.resample('D').interpolate('linear')
    

    三、Pandas滑动窗口

    为了提升数据的准确性,将某个点的取值扩大到包含这个点的一段区间,用区间来进行判断,这个区间就是窗口。例如想使用2011年1月1日的一个数据,单取这个时间点的数据当然是可行的,但是太过绝对,有没有更好的办法呢?可以选取2010年12月16日到2011年1月15日,通过求均值来评估1月1日这个点的值,2010-12-16到2011-1-15就是一个窗口,窗口的长度window=30.

    移动窗口就是窗口向一端滑行,默认是从右往左,每次滑行并不是区间整块的滑行,而是一个单位一个单位的滑行。例如窗口2010-12-16到2011-1-15,下一个窗口并不是2011-1-15到2011-2-15,而是2010-12-17到2011-1-16(假设数据的截取是以天为单位),整体向右移动一个单位,而不是一个窗口。这样统计的每个值始终都是30单位的均值。

    也就是我们在统计学中的移动平均法。

    import matplotlib.pylab
    import numpy as np
    import pandas as pd 
    %matplotlib inline
    
    df = pd.Series(np.random.randn(600),index=pd.date_range('7/1/2016',freq='D',periods=600))
    df.head()
    
    #指定该序列一个单位长度为10的滑块
    r=df.rolling(window = 10)
    r
    
    #输出滑块内的平均值,窗口中的值从覆盖整个窗口的位置开始产生,在此之前即为NaN,举例如下:窗口大小为10,前9个都不足够为一个一个窗口的长度,因此都无法取值。
    r.mean()
    
    # 通过画图库来看原始序列与滑动窗口产生序列的关系图,原始数据用红色表示,移动平均后数据用蓝色点表示:
    import matplotlib.pyplot as plt
    plt.figure(figsize=(15,5))
    df.plot(style='r--')
    df.rolling(window=10).mean().plot(style='b')#可以看到,原始值浮动差异较大,而移动平均后数值较为平稳。
    

    相关文章

      网友评论

        本文标题:Python数据分析(七):利用pandas处理时间序列数据

        本文链接:https://www.haomeiwen.com/subject/dkrjoctx.html