pandas之date_range详细说明
郝伟 2021/06/11

简介

在对二维数据进行处理时,时间序列是经常使用的一种数据类型。在pandas中,我们可以使用 pandas.date_range() 函数对数据建立时间相关的索引。在建立的过程中,需要注意以下几点:

pandas 支持 4 种常见时间概念(参考资料):

关于时间分段的三个相关概念

分段的原理是在给定的时间段时,划分出若干个时间点。在这个过程中,分段涉及了三个关键要素:

比较常用的一种方式就是date_range根据输入的时间范围和时间间隔,返回的是一序列的时间点。举例来说,“今天工作时间每小时的整点记录一次数据”。在这里的时间范围即是工作时间,比如说早九晚五就是从上午9点至下午17点的时间范围,这个时间范围对应的时间长度是8个小时,那么可以返回的时间点序列就是 [9:00, 10:00, 11:00, 12:00, 13:00, 14:00, 15:00, 16:00, 17:00] 共九个点。

实际上很多时候,时间范围进行分段并不是一件简单的事情,在分段的过程中,会因为不同的情况导致不同的结果。比如 “从 12:30 到 15:40,每小时记录一次数据” 和 “从 12:30 到 15:40,每个整点记录一次数据”,所表达的就是不同的内容,返回的结果分别是 [12:30, 13:30, 14:30, 15:30] 和 [13:00, 14:00, 15:00]。可以发现返回的时候不仅时间点不一样,结果的数量也不一样。由于在分段时,具体到时分秒时间间隔比较小,所以影响相对小些,如果是年月则会影响很大。比如,“某公司从每月15日要做一次数据报表,那么从2019/07/26成立到2021/05/20,一共做了多少次报表?”。类似这样的问题都需要有相应的计算方法或工具,因此,pandas 提供了相当多的 freq 类型以处理这些情况。

基本语法

如下所示:

pandas.date_range(
    start=None,       # 开始时间
    end=None,         # 结束时间
    periods=None,     # 时间范围长度,基于 freq 的整数个单位
    freq='D',         # 参见下文
    tz=None, 
    normalize=False,  # 未知
    name=None,        # 序列的名称
    closed=None,      # 见下面文档
    **kwargs)

主要参数说明:

date_range 函数示例

date_range 函数常用的两种类型:

根据开始时间点和间隔数生成时间点序列

根据开始时间,以一定的时间间隔,生成指定个时间点。这是相对比较容易理解的一种时间点序列的生成方式,比如:

import pandas as pd
import datetime
dr1 = pd.date_range(start='1981-07-13', periods=14580)
print(len(dr1), dr1)
14580 DatetimeIndex(['1981-07-13', '1981-07-14', '1981-07-15', '1981-07-16',
               '1981-07-17', '1981-07-18', '1981-07-19', '1981-07-20',
               '1981-07-21', '1981-07-22',
               ...
               '2021-06-03', '2021-06-04', '2021-06-05', '2021-06-06',
               '2021-06-07', '2021-06-08', '2021-06-09', '2021-06-10',
               '2021-06-11', '2021-06-12'],
              dtype='datetime64[ns]', length=14580, freq='D')

根据开始时间点和时间间隔生成时间点序列

在指定的时间范围内,以固定的时间点,生成相应的时间点序列,如下所示。

import pandas as pd
import datetime
dr2 = pd.date_range(start='1981-07-13', end='2021-06-11')
print(len(dr2), dr2)
14579 DatetimeIndex(['1981-07-13', '1981-07-14', '1981-07-15', '1981-07-16',
               '1981-07-17', '1981-07-18', '1981-07-19', '1981-07-20',
               '1981-07-21', '1981-07-22',
               ...
               '2021-06-02', '2021-06-03', '2021-06-04', '2021-06-05',
               '2021-06-06', '2021-06-07', '2021-06-08', '2021-06-09',
               '2021-06-10', '2021-06-11'],
              dtype='datetime64[ns]', length=14579, freq='D')

freq 详细说明

在 date_range 函数中,freq 是最为复杂的一个参数,不仅数量多,而且很多概念不是很直观易理解,所以本章结合代码,进行详细说明。

freq 中的 start 和 end

在选择单位的时候,由于年、季和月的跨度时间很大,所以需要指定某一天为分隔点,从而能够确定分隔的时间段。所以在freq中有大量的 start 和 end 的区别。让我们先看以下示例。

import pandas as pd
import datetime
start = datetime.datetime(2019, 1, 1)
end = datetime.datetime(2021, 06, 11)
dr1 = pd.date_range(start, end, freq='A')
dr2 = pd.date_range(start, end, freq='AS')

print(len(dr1), dr1)
print(len(dr2), dr2)

输出内容如下

2 DatetimeIndex(['2019-12-31', '2020-12-31'], dtype='datetime64[ns]', freq='A-DEC')
3 DatetimeIndex(['2019-01-01', '2020-01-01', '2021-01-01'], dtype='datetime64[ns]', freq='AS-JAN')

由此可见,由于每年的时间有很多天,所以如果选择不同的天作为分隔点,分出来的数据点的个数是不相同的。

freq 中的 close

import pandas as pd
import datetime

start = datetime.datetime(2021, 6, 11, 12, 0, 1)
end = datetime.datetime(2021, 6, 11, 13, 0, 1)

dr0 = pd.date_range(start, end, name='dr0', freq='H', closed=None)
dr1 = pd.date_range(start, end, name='dr1', freq='H', closed='left')
dr2 = pd.date_range(start, end, name='dr2', freq='H', closed='right')

print(len(dr0), dr0)
print(len(dr1), dr1)
print(len(dr2), dr2)

输出内容

2 DatetimeIndex(['2021-06-11 12:00:01', '2021-06-11 13:00:01'], dtype='datetime64[ns]', name='dr0', freq='H')
1 DatetimeIndex(['2021-06-11 12:00:01'], dtype='datetime64[ns]', name='dr1', freq='H')
1 DatetimeIndex(['2021-06-11 13:00:01'], dtype='datetime64[ns]', name='dr2', freq='H')

系数

时间间隔还可以在freq中使用系数,指定时间段,请看下面的示例。

import pandas as pd
import datetime

start = datetime.datetime(2021, 6, 11, 10, 0, 0)
end = datetime.datetime(2021, 6, 11, 11, 0, 0)

dr1 = pd.date_range(start, end, name='dr1', freq='5min')
dr2 = pd.date_range(start, end, name='dr2', freq='14min')
 
print(len(dr1), dr1)
print(len(dr2), dr2)

输出结果

13 DatetimeIndex(['2021-06-11 10:00', '2021-06-11 10:05:00',
               '2021-06-11 10:10:00', '2021-06-11 10:15:00',
               '2021-06-11 10:20:00', '2021-06-11 10:25:00',
               '2021-06-11 10:30:00', '2021-06-11 10:35:00',
               '2021-06-11 10:40:00', '2021-06-11 10:45:00',
               '2021-06-11 10:50:00', '2021-06-11 10:55:00',
               '2021-06-11 11:00'],
              dtype='datetime64[ns]', name='dr1', freq='5T')
5 DatetimeIndex(['2021-06-11 10:00', '2021-06-11 10:14:00',
               '2021-06-11 10:28:00', '2021-06-11 10:42:00',
               '2021-06-11 10:56:00'],
              dtype='datetime64[ns]', name='dr2', freq='14T')

参数列表

参考资料

journey title 分隔方式 section 工作 2021/06/11: 5: Me 2021/06/12: 3: Me 2021/06/13: 1: Me, Cat section 休息 Go downstairs: 5: Me Sit down: 5: Me
journey title 分隔方式 section 工作 2021/06/11: 5: Me 2021/06/12: 3: Me 2021/06/13: 1: Me