Pandas处理时间类型数据

时间序列数据描述

数据分析的分析对象不仅仅限于数值型和类别型两种,常用的数据类型还包括了时间类型.通过时间类型数据能够获取东岸对应的年月日和星期等信息.但时间类型数据在读入Python后常常以字符串形式出现,无法实现大部分与时间相关的分析.pandas库继承了NumPy库的datetime64以及timedelta64模块,能够快速地实现时间字符串的转换、信息提取和时间运算。

转换字符串时间为标准时间

在多数情况下,对时间类型数据进行分析的前提就是将原本为字符串的时间转换为标准时间。pandas继承了NumPy库和datetime库的时间相关模块,提供了六种时间相关的类,如下表所示。

类名称

说明

Timestamp

最基础的时间类。表示某个时间点。在绝大多数的场景中的时间数据都是Timestamp形式的时间。

Period

表示单个时间跨度,或者某个时间段,例如某一天,某一小时等。

Timedelta

表示不同单位的时间,例如1天,1.5小时,3分钟,4秒等,而非具体的某个时间段。

DatetimeIndex

一组Timestamp构成的Index,可以用来作为Series或者DataFrame的索引。

PeriodtimeIndex

一组Period构成的Index,可以用来作为Series或者DataFrame的索引。

TimedeltaIndex

一组Timedelta构成的Index,可以用来作为Series或者DataFrame的索引。

Timestamp类型

  • 其中Timestamp作为时间类中最基础的,也是最为常用的。在多数情况下,时间相关的字符串都会转换成为Timestamp。pandas提供了to_datetime函数,能够实现这一目标。
import pandas as pd
order = pd.read_table('../data/meal_order_info.csv',
      sep = ',',encoding = 'gbk')
print('进行转换前订单信息表lock_time的类型为:', 
      order['lock_time'].dtypes)
order['lock_time'] = pd.to_datetime(order['lock_time'])
print('进行转换后订单信息表lock_time的类型为:', 
      order['lock_time'].dtypes)
  • Timestamp类型时间是有限制的。最早只能够表示至1677年9月21日,最晚只能表示2262年4月11日。
print('最小时间为:', pd.Timestamp.min)
print('最大时间为:', pd.Timestamp.max)

DatetimeIndex与PeriodIndex函数

  • 除了将数据字原始DataFrame中直接转换为Timestamp格式外,还可以将数据单独提取出来将其转换为DatetimeIndex或者PeriodIndex。
dateIndex = pd.DatetimeIndex(order['lock_time'])
print('转换为DatetimeIndex后数据的类型为:\n',type(dateIndex))

periodIndex = pd.PeriodIndex(order['lock_time'],freq = 'S')
print('转换为DatetimeIndex后数据的类型为:\n',type(periodIndex))
  • 转换为PeriodIndex的时候需要注意,**需要通过freq参数指定时间间隔,常用的时间间隔有Y为年,M为月,D为日,H为小时,T为分钟,S为秒。**两个函数可以用来转换数据还可以用来创建时间序列数据,其参数非常类似。
DatetimeIndex与PeriodIndex函数及其参数说明

DatetimeIndex和PeriodIndex两者区别在日常使用的过程中相对较小,其中DatetimeIndex是用来指代一系列时间点的一种数据结构,而PeriodIndex则是用来指代一系列时间段的数据结构。

参数名称

说明

data

接收array。表示DatetimeIndex的值。无默认。

freq

接收string。表示时间的间隔频率。无默认。

start

接收string。表示生成规则时间数据的起始点。无默认。

periods

表示需要生成的周期数目。无默认。

end

接收string。表示生成规则时间数据的终结点。无默认。

tz

接收timezone。表示数据的时区。默认为None。

name

接收int,string。默认为空。指定DatetimeIndex的名字。

提取时间序列数据信息

Timestamp类常用属性

在多数涉及时间相关的数据处理,统计分析的过程中,需要提取时间中的年份,月份等数据。使用对应的Timestamp类属性就能够实现这一目的。

结合Python列表推导式,可以实现对DataFrame某一列时间信息数据的提取。

属性名称

说明

属性名称

说明

year


week

一年中第几周

month


quarter

季节

day


weekofyear

一年中第几周

hour

小时

dayofyear

一年中的第几天

minute

分钟

dayofweek

一周第几天

second


weekday

一周第几天

date

日期

weekday_name

星期名称

time

时间

is_leap_year

是否闰年

year1 = [i.year for i in order['lock_time']]
print('lock_time中的年份数据前5个为:',year1[:5])
month1 = [i.month for i in order['lock_time']]
print('lock_time中的月份数据前5个为:',month1[:5])
day1 = [i.day for i in order['lock_time']]
print('lock_time中的日期数据前5个为:',day1[:5])
weekday1 = [i.weekday_name for i in order['lock_time']]
print('lock_time中的星期名称数据前5个为:',weekday1[:5])

在DatetimeIndex和PeriodIndex中提取信息

  • 在DatetimeIndex和PeriodIndex中提取对应信息可以以类属性方式实现。
  • 值得注意的是PeriodIndex相比于DatetimeIndex少了weekday_name属性,所以不能够用该属性提取星期名称数据。若想要提取信息名称可以通过提取weekday属性,而后将0-6四个标签分别赋值为Monday至Sunday。
print('dateIndex中的星期名称数据前5个为:\n',
      dateIndex.weekday_name[:5])
print('periodIndex中的星期标号数据前5个为:',
      periodIndex.weekday[:5])

加减时间数据

Timedelta类

Timedelta是时间相关的类中的一个异类,不仅能够使用正数,还能够使用负数表示单位时间,例如1秒,2分钟,3小时等。使用Timedelta类,配合常规的时间相关类能够轻松实现时间的算术运算。目前Timedelta函数中时间周期中没有年和月。所有周期名称,对应单位及其说明如下表所示。

周期名称

单位

说明

周期名称

单位

说明

weeks


星期

seconds

s


days

D


milliseconds

ms

毫秒

hours

h

小时

microseconds

us

微妙

minutes

m


nanoseconds

ns

纳秒

  • 使用Timedelta ,可以很轻松地实现在某个时间上加减一段时间 。
## 将lock_time数据向后平移一天
time1 = order['lock_time']+pd.Timedelta(days = 1) 
print('lock_time在加上一天前前5行数据为:\n',order['lock_time'][:5])
print('lock_time在加上一天前前5行数据为:\n',time1[:5])
  • 除了使用Timedelta实现时间的平移外,还能够直接对两个时间序列进行相减,从而得出一个Timedelta。
timeDelta = order['lock_time'] - pd.to_datetime('2017-1-1')
print('lock_time减去2017年1月1日0点0时0分后的数据:\n',
      timeDelta[:5])
print('lock_time减去time1后的数据类型为:',timeDelta.dtypes)

实现

时间字符串转换位标准时间格式

在订单信息表中存在两个时间特征,use_start_time和lock_time,分别代表了开始点餐的时间和结算订单的时间。需要将这两个特征转换为标准的时间格式

# 订单信息表时间数据转换
import pandas as pd
order = pd.read_table('../data/meal_order_info.csv',sep=',',encoding='gbk')
order['use_start_time'] = pd.to_datetime(order['use_start_time'])
order['lock_time'] = pd.to_datetime(order['lock_time'])
print('进行转换后订单信息表use_start_time和lock_time的类型为:\n',order[['use_start_time','lock_time']].dtypes)

提取菜品数据中年月日和星期信息

use_start_time和lock_time两个特征中的时间信息基本一致,故只需要提取其中一个特征的时间信息即可。

# 提取菜品数据中年月日和星期信息
year = [i.year for i in order["lock_time"]]    # 提取年份信息
month = [i.month for i in order["lock_time"]]  # 提取月份信息
day = [i.day for i in order["lock_time"]]      # 提取日期信息
week = [i.week for i in order["lock_time"]]    # 提取周信息
weekday = [i.weekday() for i in order["lock_time"]]    #提取星期信息
## 提取星期名称信息
weekname = [i.weekday_name for i in order['lock_time']]
print('订单详情表中的前5条数据的年份信息为:',year[:5])
print('订单详情表中的前5条数据的月份信息为:',month[:5])
print('订单详情表中的前5条数据的日期信息为:',day[:5])

查看订单信息表时间统计信息

通过求取最早时间和最晚时间的差值来计算整体订单的时间跨度,还能够将use_start_time和lock_time两个特征做加减运算。

# 查看订单信息表时间统计信息
timemin = order['lock_time'].min()
timemax = order['lock_time'].max()
print('订单最早的时间为:',timemin)
print('订单最晚的时间为:',timemax)
print('订单持续的时间为:',timemax-timemin)

chekTime = order['lock_time'] - order['use_start_time']
print('平均点餐时间为:',chekTime.mean())
print('最小点餐时间为:',chekTime.min())
print('最大点餐时间为:',chekTime.max())