【python】字符串日期格式数据处理

前言

特征工程中经常性遇到字符串形式的日期数据,通常我们需要将其转换成计算机能够理解的datetime对象,好处在于可以实现日期早晚的比较(例如要筛选出2019-01-022019-03-04内的数据),日期的加减法等系列操作。python实现该操作的模块是datetime,同时数据分析处理工具pandas也提供了相应的时间格式处理方法to_datetime(),本文从实用性角度出发,简要讲解这两种时间格式处理方式,并以一个具体的例子实际演示如何使用。

注:本文关心的是对于给定的字符串类型时间数据,如何快速进行读取实例化,因此不会大篇幅地去详细介绍模块的各个功能。

datetime

由于datetime包含了众多对时间数据的处理、初始化操作,一一学习并没有特别大的效益,且很容易忘记,因此,适合在必要的时候查询使用。这里提供一篇对datetime使用讲解十分详细的文章:Python datetime模块详解、示例

作者从datetime模块下所有的类进行了详细的介绍和使用,并附上了日期格式化符号,可以在需要的时候进行查询。

datetime处理字符串时间数据

主要用到了datetime.datetime.strptime(),能够根据指定的日期格式符号,从字符串中抽取得到datetime实例。例如:

from datetime import datetime
datetime.strptime('2019-01-03','%Y-%m-%d')  # datetime.datetime(2019, 1, 3, 0, 0)

%Y(四位年份),%m(月份),%d(月内中的一天)是日期的格式化符号,更多的符号含义参考上面给的文章,会自动检验日期的合法性,例如2月不可能有30号。
转换成datetime实例后,就可以做很多日期的骚操作了,例如:

  • 比较两个日期的早晚
    from datetime import datetime
    a = datetime.strptime('2019-02-20','%Y-%m-%d')
    b = datetime.strptime('2029-02-20','%Y-%m-%d')
    a < b  # True
  • 计算两个日期相差间隔
    from datetime import datetime
    a = datetime.strptime('2019-02-20','%Y-%m-%d')
    b = datetime.strptime('2029-02-20','%Y-%m-%d')
    b-a  # datetime.timedelta(days=3653)
    这个方法的缺点是一次只能处理单个时间字符串,若要处理大量的时间数据,就需要用for循环,开销上不如pandas.to_datetime

pandas.to_datetime

pandas.to_datetime()接收Series或列表等结构的数据,对其中所有字符串时间数据进行格式化操作,转换成datetime类型。例如:

import pandas as pd
dates = ['2019-1-29','2018/03/27','2017-09-3']
pd.to_datetime(dates,format='%Y-%m-%d')   # DatetimeIndex(['2019-01-29', '2018-03-27', '2017-09-03'], dtype='datetime64[ns]', freq=None)

在上面的例子中我可以对分隔符和0前缀进行了变动,可以发现并不影响最终的结果

to_datetime还包含几个重要的参数:

  • errors
    • ignore: 忽略解析错误,按照原始输入进行输出,用于在字符串中出现未知分割符号的时候,如2019#08@13
    • raise(default): 但发现有无法解析的日期字符串时,报错
    • coerce: 将无法解析的字符串删除为NaT
  • dayfirst: 日优先,在有的地方会把日期放到最前面,形成日/月/年的形式,如10/11/12 解析为2012-11-10
  • yearfirst: 年优先,适用于2位的年份,如10/11/12解析为2010-11-12,但dayfirst,yearfirst同时为Trueyearfirst优先级更高

返回的时候根据传入的数据结构类型不同,返回结果也不同:

  • 列表(或类似数据结构): DatetimeIndex
  • Series: Series datetime64 类型
  • 标量: Timestamp

to_datetime处理时间戳数据

有的时候给我们的数据以时间戳的方式存储成字符串,例如1490195805,相应的用to_datetime处理如下:

  • 以秒为单位
    pd.to_datetime(1490195805, unit='s')  # Timestamp('2017-03-22 15:16:45')
  • 以纳秒为单位
    pd.to_datetime(1490195805433502912, unit='ns') #  Timestamp('2017-03-22 15:16:45.433502912')

实际应用

假设我们有如下的一组每日降雨记录的数据,每天记录是否降雨:

现在我们希望知道在2019-02-012019-02-02时间内降雨的次数。则可通过如下代码实现:

data = pd.DataFrame({'isRainFall':[1,0,1],'date':['2019-02-01','2019-02-02','2019-02-03']})
data['date'] = pd.to_datetime(data['date'],format='%Y-%m-%d')  # 将字符串时间转换成datetime
start_date = pd.to_datetime('2019-02-01',format='%Y-%m-%d')
end_date = pd.to_datetime('2019-02-02',format='%Y-%m-%d')
data[(data['date'] >= start_date) & (data['date'] <= end_date)]['isRainFall'].sum()  # 1