工控课堂

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

工控课堂 首页 工控文库 工控编程 查看内容

Python datetime 教程:操作时间、日期与时间跨度

2020-2-9 18:58| 发布者: gkket| 查看: 1| 评论: 0|原作者: gkket

摘要: 在 Python 中处理日期和时间有点麻烦。所幸,Python 提供了一种内置的方式来简化这种操作:Python 的 Datetime 模块。 datetime 可以帮助我们识别并处理与时间相关的元素,如日期,小时,分钟,秒,星期,月份,年份 ...
在 Python 中处理日期和时间有点麻烦。所幸,Python 提供了一种内置的方式来简化这种操作:Python 的 Datetime 模块。

datetime 可以帮助我们识别并处理与时间相关的元素,如日期,小时,分钟,秒,星期,月份,年份等。它提供了诸如时区和夏令时等很多服务。还可以处理时间戳数据,解析星期几,每月几号,以及从字符串格式化日期和时间等。

简而言之,datetime 是 Python 中处理日期和时间的一大利器。我们现在来深入了解一下。

本节教程中,我们将会学习很多 datetime 中很多详细的方法,包括:
  • 创建日期对象 Date
  • 从日期中获取年份和月份
  • 从日期中获取每月几号和星期几
  • 从日期中获取小时和分钟
  • 从日期中获取一年中的第几周
  • 日期对象转换成时间戳
  • Unix 时间戳字符串转换成日期对象
  • 处理时间差对象 timedelta
  • 比较两个日期和时间之间的差值
  • 日期格式化:strftime() 和 strptime()
  • 时区处理
  • 使用 Pandas 中的 datetime 对象

  • 获取年,月,日,时,分
  • 获取星期几与一年中的第几天
  • 转换日期对象为 DataFrame 索引


学习本教程时,我们建议你在自己的机器上运行一下这些代码。

Python 的 datetime 类
在编写代码之前,有必要先了解一下 datetime 模块中提供的五个主要的对象类。根据我们具体需要执行的操作,我们可能需要使用其中的一个或多个类。
  • datatime:允许我们同时操作时间和日期(月,日,年,时,秒,微秒)。
  • date:允许我们排除时间仅操作日期(月,日,年)
  • time:允许我们排除日期仅操作时间(时,分,秒,微秒)
  • timedelta:一个用于操作日期以及测量的时间跨度
  • tzinfo:一个用于处理时区的抽象类


如果还是不太理解它们之间的区别,也没关系。我们接下来就深入学习一下 datetime 的工作方式,来更好地理解和使用它们。

创建 Date 对象
首先,我们来仔细看看 datetime 对象。由于 datetime 既是模块名也是模块内的类名,所以我们要从 datetime模块内引用 datetime 类。

然后,打印当前日期和时间来查看 datetime 对象中都包含什么。可以使用 datetime 类的 .now() 函数创建一个 datetime 对象,然后打印这个对象,之后再使用 type() 函数打印这个对象的类型。如此,我们可以看到更详细的信息。
从上面的结果中,我们可以看到 datetime_object 是 datetime 类的对象实例,对象中包含了年,月,日,时,分,秒,以及毫秒。

从 Date 中提取年份和月份
我们现在已经理解了 datetime 对象的构成,那么我们可以猜一下 date 和 time 对象是怎样的。因为我们已经知道 date 对象可以理解为 datetime 去掉了时间数据,而 time 对象可以理解为 datetime 去掉了日期数据。

我们还可以解决很多问题。比如,大多数数据集中,日期和时间信息是以字符串格式存储的。另外,我们可能不希望拿到所有的日期和时间数据,当我们在做一些诸如月度销售分析的时候,那么将信息分解到毫秒级别的用处并不大。

现在,我们来聚焦于数据科学中的一项常见任务:使用 datetime 从字符串中提取我们实际想要的元素。

为了实现这个目的,我们还需要做一些其他的工作。

使用 strptime() 和 strftime() 处理日期和时间字符串
幸运的是,datetime 提供了两个方法,strptime() 和 strftime(),可以在字符串与 datetime 对象之间互相转换。strptime() 可以读取字符串中的日期与时间信息并将其转换为 datetime 对象,而 strftime 则是将 datetime 对象转换为字符串。

当然,strptime() 并没有魔法,它不能将任意字符串转换为日期和时间,它需要一些人为地帮助,来解释它究竟识别到了什么。但是它只能识别大多数常规的日期和时间字符串格式(详情请查阅文档)。我们现在给定一个日期格式字符串 "YYYY-MM-DD",来看看 strptime() 方法能做什么。
可以看到 strptime() 方法接收两个参数:字符串 my_string 以及 "%Y-%m-%d",多出来的这个字符串告诉 strptime() 方法如何解释传入的字符串 my_string。比如,"%Y" 表示期望从字符串的前四个字符中读取年份。

这篇文档中完整地列出了这些可匹配的模式,我们将在教程后面的部分详细介绍这些方法。

你可能还注意到日期后面还跟着时间信息 00:00:00。这是因为我们创建了一个 datetime 对象,必然会包含日期和时间。如果我们在输传入的字符串中没有指明时间,将会用 00:00:00 作为默认时间。

>>> 今日签到口令:9nad <<<

先不论其他,我们希望的是从日期中分离出特定的元素用于分析。一个办法是使用 datetime 对象内置的类属性,如 .month 或 .year。

从 Date 获取每月的某天和一周的某天
我们现在来提取更多的信息,这也确实是一个常见的任务。此时,我们将尝试从 my_date 对象中获取月份中某一天以及年份中的某一天。通过 datetime 对象的 .weekday() 函数可以得到一个星期几的数字,但是我们可以通过使用 calendar 模块中的 day_name 方法将其转化为文本格式(如,Monday,Tuesday,Wednesday 等等)。

我们首先会导入 calendar,之后会用到 my_date 对象的 .day 属性以及 .weekday() 方法。这样我们就可以获取到星期几的文本格式:
先等一下,这里看起来有一点奇怪。一周的第三天应该是 Wednesday 而不是 Thursday 啊。

我们这里使用一个循环来仔细看一下 day_name 变量中的信息:
现在我们知道 Python 中星期是从 Monday 开始的,其计数下标则是从 0 开始而不是从 1 开始。所以这就解释了我们上面看到的为什么数字 3 转换成了 "Thursday"。

从 Python 的 Datetime 对象中获取小时和分钟
我们现在来关注一下时间以及从 datetime 对象中提取小时和分钟。与上面我们处理月份和年份相似,我们可以使用类属性 .hour 和 .minute 获取到一天中小时与分钟信息。

使用 .now() 函数来设置一个新的日期和时间。当写到这里的时候,时间是 2019 年 10 月 25 日上午 10 点 25 分。当然,根据你运行这段代码的时间,结果可能与之不同。

从 Datetime 对象中获取一年中的星期数
我们还可以使用 datetime 做很多有趣的事。例如,我们可能想知道现在是一年中的第几个星期。

使用 datetime 对象的 isocalendar 函数,我们可以获取到年份,一年中的星期数,和一周中的第几天。

特别注意,isocalendar 返回的是带有 ISO 年份,星期数和工作日的元组。这个 ISO 日历是基于格里高利历的一种被广泛使用的标准日历。你可以点击链接了解更多详细信息。但是出于我们现在的目的,我们只需要知道它是作为一种常规日历,且每星期是从星期一开始的就可以了。
注意,在 ISO 日历中,每星期是从 1 开始计数的,所以这里的 5 真正表示的是星期五:Friday。

从上面我们可以看到当前是今天的第 43 个星期,但是如果你只想获得这个数字,可以像其他 Python 中的列表或元组一样,使用下标索引的方式实现:

将 Date 对象转换为 Unix 时间戳,反之亦然
编程的时候,会经常遇到使用时间戳格式存储的时间和日期,或者希望以 Unix 时间戳格式存储你的数据。

我们可以使用 datetime 的内置函数 timestamp(),他可以接收一个 datetime 对象作为参数并返回一个时间戳格式的日期和时间:
与之相似,我们可以使用 fromtimestamp() 执行与上面相反的操作。这是 datetime 类中提供的一个方法,可以接收一个(浮点型格式的)时间戳作为参数,并返回一个 datetime 对象,像下面这样:

使用 Timedelta 对象测量时间跨度

很多时候,我们可能希望使用 Python 中的 datetime 来测量一段时间跨度,或者一段持续的时间。这个可以使用 datetime 内置的 timedelta 类。一个 timedelta 对象可以表示两个日期或时间的差值。有了这个我们就可以测量时间跨度,或者对日期及时间进行加减操作等。

将所有参数置为 0 即可创建一个默认的 timedelta 对象。现在我们来创建一个时间跨度为两周的 timedelta 对象:
注意,这里我们使用 timedelta 类的 .days 属性来获取以天为单位的持续时间。参照文档,我们还可以获取以秒和毫秒为单位的持续时间。

现在创建另一个 timedelta 持续时间再练习一下:
现在我们结合使用 datetime 对象和 timedelta 对象来做一些数学计算。比如说在当前日期和时间上加上一些不同的时间跨度,来看看十五天后的日期,或者是两周前是哪天。

为此,我们可以使用运算符 + 或 - 来对 datetime 对象增加或减去 timedelta 对象实现。得到的结果是 datetime 加上或减去 timedelta 对象所代表的的时间跨度后的新时间。是不是很棒?

(注意:在下面的代码中,时间是 10 月 25 日 11:12。这可能与你实际使用 .now() 函数得到的 datetime 对象有所不同。)
注意,这里计算后输出的结果仍然是一个 datetime 对象。

比较两个日期和时间之间的差值
与上面的操作类似,我们还可以使用 datetime 来为一个日期加上或减去另一个日期,来得到一个时间跨度。

由于计算的结果是一个时间片,当我们对一个日期对象减去另一个日期对象得到的就是一个 timedelta 对象。

这里,我们创建了两个日期对象(注意,它们与 datetime 对象相比,除了不包含时间信息,其他都是一样的),并且让其中一个减去另一个得到一个时间跨度。
上述代码,我们为了简单起见仅使用了日期 date,同样也可以使用 datetime 对象做同样的操作,以获得包含小时,分钟和秒的精确量度:

格式化日期:有关 strftime() 和 strptime() 的更多信息

我们先前已经简单地了解了 strftime() 和strptime() 对象,现在来仔细看一下这些方法,因为它们对于 Python 中处理数据分析通常比较重要。

我们已经使用过 strptime() 方法,你可以将一个格式化后的日期和时间转换为一个 datetime 对象,函数格式如下:
注意这里有两个参数:
  • string:格式化后待转化的字符串
  • format:指定时间字符串的格式,以便 strptime() 可以正确解析


现在来试着转换一个其他类型的日期字符串。这个网站提供了很多非常有用的参考说明,有助于 strptime() 识别我们输入的字符串:
现在来做一些更高级的操作,验证一下目前所学。以一个格式化后的字符串开始,将其转换为 datetime 对象,并且看看不同的格式化方式(dd/mm 和 mm/dd)得到的结果。

然后,基于 mm/dd 的格式,我们将其转换为 Unix 时间戳。之后转回 datetime 对象,再使用几种不同的 strftime 模式将转换后的字符串输出:

这里有一张图片,可以保存在你常用的备忘录中,里面是常用的 strftime() 和 strptime() 模式:

现在使用上面的模式做一些简单的实践:

处理时区
在 Python 中,如果涉及时区的话,处理日期和实践就会变得很复杂。幸好,pytz 模块的存在为我们提供了跨时区转换的能力,它还可以在使用夏令时的地区处理夏令时。

我们可以通过 localize 函数为 Python 中的 datetime 对象加上一个时区信息。然后可以用 astimezone() 将一个已有时区转换为另一个指定的时区(这个函数接收一个我们期望转换的时区作为参数)。
有了这个模块,我们在处理包含多个不同时区的数据集会变得简单很多。

处理 pandas 中的 Datetime 对象
数据科学家热衷于 pandas 有很多原因。其中之一是它包含了多种用于处理时间序列数据的功能。拿 datetime 自身来说,pandas 中就有 datetime 和 timedelta 对象分别表示日期和时间以及时间片。

我们将日期,时间和时间片字符串通过以下函数转换为 pandas 中的 datetime 对象。
  • to_datetime() :将日期字符串转换为 Python 中的 datetime对象。
  • to_timedelta() :找出以天,小时,分钟或秒为单位的时间差值。


可以预见,这些函数都很善长将字符串转换为 Python 中的 datetime 对象,而且可以自动识别它们的格式,而不需要我们定义 strftime 模式。
来看一个实际的例子:
注意,即使我们在字符串中带有一些复杂的元素,如 "th" 和 "sep" 而不是指明 "Sep." 或 "September",pandas 也可以正确的解析该字符串并返回格式化后的日期。

我们还可以通过 pandas(以及一些与之相关的 numpy 的功能) 自动创建一段范围内的 pandas 对象序列。比如下面这样,我们从上面定义的日期开始,创建了一系列十二个日期。然后又用 pd.date_range() 函数创建了另外一系列日期:

使用 pandas 获取年,月,日,时,分
对 pandas 的 DataFrame 中每一列使用 dt 属性,我们能够轻易地从日期中获取年,月,日,时,或分。比如,我们可以使用 df['date'].dt.year 从一个包含完整日期信息的 pandas 数据列中单独解析出年份。

为了方便理解,我们利用上面已经创建的一个序列快速实现一个 DateFrame:

现在使用 Python 中 datetime(通过 dt) 相关的属性为日期的每个元素创建一个单独的列:

获取星期几和一年中的某天
Pandas 还可以从 datetime 对象中获取其他的一些元素,比如说星期几和一年中的某一天。这些同样可以用 dt属性来实现。这里注意一点,Python 中通常每周从周一开始,而下表是 0 ,所以星期的数字 5 表示周六。

将 Date 对象转换成 DateFrame 索引
我们还可以在 pandas 中将一个 datetime 的列写入 DateFrame 的索引中。这对于处理一些数据可视化的任务很有用,matplotlib 可以识别出 DateFrame 的索引列是一个时间序列,然后绘制相应的数据。

为了实现这一点,我们需要重新定义 df.index :

总结
本教程中,我们深入讨论了 Python 中的 datetime,并且还学习了 pandas 及其 calendar 模块的一些知识。我们已经介绍了很多东西,不过要记住:最好的学习方式是亲自动手写代码。

英文原文:https://www.dataquest.io/blog/python-datetime-tutorial/
译者:居老师的龙尾巴

路过

雷人

握手

鲜花

鸡蛋

相关阅读

最新评论

热门文章

QQ|免责声明|本站介绍|工控课堂 ( 沪ICP备14007696号-3 )|网站地图

GMT+8, 2020-2-9 18:58 , Processed in 0.051782 second(s), 41 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

返回顶部