Pandas是在金融建模的背景下开发的,因此它包含了一套相当广泛的工具,用于处理日期、时间和带时间索引数据的处理工具。
🐼君今天和大家聊聊日期和时间数据的三种类型:
时间戳指的是某个具体的时间点。(例如,2018年10月10日早上9点)
时间间隔和周期表示特定的开始时间点和结束时间点之间的时间长度。例如,2018年(指的是2018年1月1日至2018年12月31日这段时间间隔)周期通常指的是时间间隔的一种特殊形式,其中每个间隔的长度是一致的,彼此之间不会重叠。(例如,以24小时为周期构成每一天)
时间增量time delta或持续时间duration表示精确的时间长度(例如,持续时间为27.36秒)
在本文中,我们将介绍如何在Pandas中处理这3种类型的日期/时间数据。
限于篇幅,无法对Python或Pandas中可用的时间序列工具进行详尽的介绍,而是通过一个广泛的讨论,总结用户应该如何处理时间序列。
我们将首先简要介绍在Python中处理日期和时间数据的工具,然后再具体了解Pandas提供的工具。
最后,我们将通过一些简短的例子来演示Pandas中处理时间序列数据的方法。
# Python的日期与时间工具
在Python世界里有许多可用的日期、时间、时间增量和时间跨度(timespans)的表示方法。
尽管Pandas提供的时间序列工具往往更适合用来处理数据科学问题,但了解Pandas与Python标准库以及第三方库中使用的其他时间序列工具之间的关联性还是很有帮助的。
## 原生Python的日期和时间工具:datetime和dateutil
Python 用于处理日期和时间的基本对象位于内置的 datetime 模块中。
如果与第三方库 dateutil 模块一起搭配使用,可以快速实现一系列处理日期和时间的功能。例如,可以使用 datetime 类型手动建立一个日期:
或者,使用 dateutil 模块,你可以从各种字符串格式中正确解析日期:
一旦有了datetime 对象,就可以进行许多操作了,比如打印出这一天是星期几:
在最后一行代码中,我们使用了一个标准的字符串格式(standard string format)代码来打印日期 ("%A"),你可以在 Python 的 datetime 文档(https://docs.python.org/3/library/datetime.html)的 strftime 部分阅读(https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior)。
其他有用的日期使用程序的文档可以在 dateutil 的在线文档中找到。
需要注意的一个相关程序包是 pytz(http://pytz.sourceforge.net/),它包含了用于处理时间序列数据中最容易引起迁移的部分:时区(time zones)
datetime 和 dateutil 的强大之处在于它们的灵活性和简单的语法:你可以使用这些对象和它们的内置方法来轻松地执行你可能感兴趣的任意操作。
但如果你希望处理的日期和时间数据量比较大,那么速度就会比较慢:就像 Python 的原生列表对象没有 NumPy 中已经被编码的数值类型数组的性能好一样,Python 原生日期 datetime 对象列表也同样没有 NumPy 中已经被编码的日期(encoded dates)类型数组的性能好。
## 时间类型数组:NumPy 的 datetime64 类型
Python的原生日期datetime格式的性能弱点促使 NumPy 团队为 NumPy 添加了自己的时间序列数据类型。
datetime64 类型将日期编码为64位整数,这样可以非常紧凑地表示日期数组,来节省内存。
datetime64 需要一个确定具体的输入类型:
然而,一旦我们对这个日期进行了格式化处理,我们就可以很快地对它进行向量化操作运算:
由于 NumPy datetime64 数组中元素的类型是统一的,所以这种类型的数组运算速度会比我们直接处理 Python 的 datetime 对象运算速度要快得多,特别是在处理较大数组时。
datetime64 和 timedelta64 对象的一个共同特点是,它们都是在基本时间单位(fundamental time unit)的基础上建立的。
因为 datetime64 对象被限制在64位精度,所以可编码的时间范围是这个基本单元的2^64倍。
datetime64 在时间精度(time resolution)和最大时间跨度(maximum time span)之间达成了一种平衡。264" role="presentation" style=" box-sizing: border-box; display: inline; line-height: normal; font-size: 16px; text-align: left; overflow-wrap: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; color: rgb(0, 0, 0); font-family: "Source Sans Pro", sans-serif; background-color: rgb(255, 255, 255); ">
例如,如果你想要的时间精度是一个纳秒(nanosecond,ns)级,那么你就可以将时间编码到0-2^64纳秒或者600年之内,NumPy 将从输入中推断出所需使用的时间单位。
例如,下面是一个以天为单位的日期:
这里是一个以分钟为单位的日期:
这里需要注意的是,时区会自动设置为执行代码的操作系统上的当地时区。
你可以通过使用各种格式的代码设置基本时间单位。例如,将时间单位设置为纳秒:
下表来自NumPy datetime64文档,列出了所有支持相对和绝对时间跨度的时间与日期单位格式代码:
对于我们我们日常工作中的时间数据类型,默认单位都是纳秒 datetime64[ns],因为用它来表示时间范围精度可以满足绝大部分需求。
最后,我们还需要注意的是,虽然 datetime64 数据类型弥补了 Python 原生的 datetime 类型的一些不足,但它缺少许多由 datetime,尤其是 dateutil 提供的便捷的方法和函数。
更多信息可以在 NumPy 的 datetime64 文档中找到(https://numpy.org/doc/stable/reference/arrays.datetime.html)。
## Pandas的日期和时间工具:理想与现实的最佳解决方案
Pandas 的所有关于日期与时间的处理方法全部都是通过 Timestamp 对象实现的,它利用了numpy.datetime64 的高效存储和向量化接口将 datetime 和dateutil 的易用性有机结合起来。
Pandas通过一组 Timestamp 对象就可以创建一个可以作为 Series 或 DataFrame 索引的 DatetimeIndex,下面我们会看到很多这样的例子。
例如,我们可以使用Pandas的方式来演示前面介绍的日期与时间功能。
我们可以灵活处理不同格式的日期与时间字符串,获取某一天是星期几:
此外,我们还可以直接在这个对象上进行NumPy式的向量化操作:
在下一篇文章中,我们将更深入地了解利用Pandas提供的工具来操作时间序列数据。