10. 处理时间序列

Pyhton处理时间序列常用的包有datetime,dateutil,但同样也存在性能弱的问题,pandas为了处理的大量时间相关数据,把时间相关数据作为datetime64类型进行处理,相对来讲,这种数据类型节省内存,处理起来速度快。

在pandas中,增加了Timestamp对象,所有日期与时间的处理方法都是通过Timestamp实现。

numpy/pandas利用Timestamp和datetime64的数据类型,将python的日期处理包datetime和dateutil有机结合起来,可以实现对日期数据的高效灵活处理。

10.1. datetime64 数据类型

datetime64是numpy处理时间相关内容的数据类型,可以对时间类型数据做灵活处理,同时还可以支持各种时间单位的操作。

常见的时间单位是:

  • Y: Year
  • M: Month
  • W: Week
  • D: Day
  • h: Hour
  • m: Minute
  • s: Second
  • ms: millisecond
  • us: micorosecond
  • ns: nanosecond
  • ps: picosecond
  • fs: femtosecond
  • as: attosecond
import numpy as np

# datetime64数据类型
date = np.array("20180-03-12", dtype=np.datetime64)
print(date)
20180-03-12
# 向量化操作
d = date + np.arange(5)
print(d)
['20180-03-12' '20180-03-13' '20180-03-14' '20180-03-15' '20180-03-16']
# 添加时间单位, 此处采用的是ns
a = np.datetime64("2019-01-13 12:45:32.30", "ns")
print(a)
2019-01-13T12:45:32.300000000

10.2. Timestamp

import pandas as pd

# 利用pd.to_datetime可以将多种不同的格式时间进行处理
date = pd.to_datetime("5th of June, 2019")
print(date)
# date可以使用时间格式化功能
print(date.strftime("%A"))
2019-06-05 00:00:00
Wednesday
# 支持向量化操作

# 按天计算, 进行向量化
d = date + pd.to_timedelta(np.arange(10), "D")
print(d)
DatetimeIndex(['2019-06-05', '2019-06-06', '2019-06-07', '2019-06-08',
               '2019-06-09', '2019-06-10', '2019-06-11', '2019-06-12',
               '2019-06-13', '2019-06-14'],
              dtype='datetime64[ns]', freq=None)

10.3. 时间做索引

idx = pd.DatetimeIndex(['2019-01-01', '2019-02-01','2019-03-01',
                       '2019-04-01','2019-05-01','2019-06-01'])

date = pd.Series(range(6), index=idx)
print(date)
2019-01-01    0
2019-02-01    1
2019-03-01    2
2019-04-01    3
2019-05-01    4
2019-06-01    5
dtype: int64
#既然是索引,就可以使用来进行数据的提取
# 切片包含结束位置
print(date[ '2019-02-01':'2019-06-01'])
2019-02-01    1
2019-03-01    2
2019-04-01    3
2019-05-01    4
2019-06-01    5
dtype: int64
# 一些特殊的时间操作
# 可以通过年费切片获取概念的全部数据
print(date["2019"])
2019-01-01    0
2019-02-01    1
2019-03-01    2
2019-04-01    3
2019-05-01    4
2019-06-01    5
dtype: int64

10.4. pandas时间序列的数据结构

pandas对时间序列准备了几个特殊的数据结构:

  • pd.DatetimeIndex: 针对时间戳数据
  • pd.PeriodIndex: 针对时间周期数据
  • pd.TimedeltaIndex: 针对时间增量或持续时间
# pd.to_datetime传输一个时间日期会返回一个Timestamp类型数据
# 传递时间序列会返回DatetimeIndex类型数据
from datetime import datetime

dates = pd.to_datetime([datetime(2019,4,3), '5th of June, 2018', '2017-Jul-9',
                       "09-02-2018", '20190105'])
# 对一个时间序列,会返回DatetimeIndex类型数据
print(dates)
DatetimeIndex(['2019-04-03', '2018-06-05', '2017-07-09', '2018-09-02',
               '2019-01-05'],
              dtype='datetime64[ns]', freq=None)
# DatetimeIndex 类型通过 pd.to_period和一个频率代码可以转换成PeriodIndex类型
d = dates.to_period('D')
print(d)
PeriodIndex(['2019-04-03', '2018-06-05', '2017-07-09', '2018-09-02',
             '2019-01-05'],
            dtype='period[D]', freq='D')
# 当用一个日期减去一个日期,返回的是TimedeltaIndex类型

d = dates - dates[0]
print(d)
TimedeltaIndex(['0 days', '-302 days', '-633 days', '-213 days', '-88 days'], dtype='timedelta64[ns]', freq=None)

10.5. xxx_range类函数

pandas提供了可以规律产生时间序列的函数, 此类函数的使用和range类似,pandas提供了三个函数:

  • pd.date_range: 可以处理时间戳,
  • pd.period_range:可以处理周期
  • pd.timedelta_range:可以处理时间间隔
d = pd.date_range("2018-03-03", "2018-12-02", periods=5)
print(d)
DatetimeIndex(['2018-03-03 00:00:00', '2018-05-10 12:00:00',
               '2018-07-18 00:00:00', '2018-09-24 12:00:00',
               '2018-12-02 00:00:00'],
              dtype='datetime64[ns]', freq=None)
d = pd.date_range("2018-03-03", "2018-12-02", freq="M")
print(d)
DatetimeIndex(['2018-03-31', '2018-04-30', '2018-05-31', '2018-06-30',
               '2018-07-31', '2018-08-31', '2018-09-30', '2018-10-31',
               '2018-11-30'],
              dtype='datetime64[ns]', freq='M')
d = pd.period_range("2018-01-01", periods=5, freq="M")
print(d)
PeriodIndex(['2018-01', '2018-02', '2018-03', '2018-04', '2018-05'], dtype='period[M]', freq='M')
d = pd.timedelta_range(0, periods=5, freq="H")
print(d)
TimedeltaIndex(['00:00:00', '01:00:00', '02:00:00', '03:00:00', '04:00:00'], dtype='timedelta64[ns]', freq='H')