[numpy learning 03]时间日期和时间增量,Numpy,学习

发表时间:2020-10-22

引言

本章我们学习Numpy数据类型的时间日期(datetime64)和时间增量(timedelta64)

在 numpy 中,我们很方便的将字符串转换成时间日期类型 datetime64 datetime 已被 python 包含的日期时间库所占用)。

datatime64 是带单位的日期时间类型,其单位如下:

日期单位 代码含义 时间单位 代码含义
Y h 小时
M m 分钟
W s
D ms 毫秒
- - us 微秒
- - ns 纳秒
- - ps 皮秒
- - fs 飞秒
- - as 阿托秒

秒、毫秒、微bai秒、纳秒、皮秒、飞秒、阿托秒每两级之du间的换算进率为1000。

其中1阿秒等于光飞越3粒氢阿子的时间。

比例上,一阿秒之于一秒,如同一秒之于 317.1 亿年,约为宇宙年龄的两倍。

1、datetime64的使用:

【例1-1】datetime64的使用 自动选择对应单位

>>>import numpy as np
>>>a = np.datetime64('2020-10')
>>>print(a,a.dtype)
2020-10 datetime64[M]

>>>b = np.datetime64('2020-10-20')
>>>print(b,b.dtype)
2020-10-20 datetime64[D]

>>>c = np.datetime64('2020-10-20 19')
>>>print(c,c.dtype)
2020-10-20T19 datetime64[h]

>>>d = np.datetime64('2020-10-20 19:37')
>>>print(d,d.dtype)
2020-10-20T19:37 datetime64[m]

>>>e = np.datetime64('2020-10-20 19:37:21')
>>>print(e,e.dtype)
2020-10-20T19:37:21 datetime64[s]
...

【例1-2】datetime64的使用 指定使用的单位

在这里,只用一个例子说明:

>>>a = np.datetime64('2020-10', 'D')
>>>print(a)
2020-10-01

我们再来判断一下‘2020-10’和‘2020-10-01’的关系:

>>>import numpy as np
>>>print(np.datetime64('2020-10') == np.datetime64('2020-10-01'))
True

由上例可以看出,2020-10 和 2020-10-01 所表示的其实是同一个时间。
事实上,如果两个 datetime64 对象具有不同的单位,它们可能仍然代表相同的时刻。并且从较大的单位(如月份)转换为较小的单位(如天数)是安全的。

【例1-3】字符串创建日期时间数组(详尽效应)

>>>import numpy as np
>>>a = np.array(['2020-10', '2020-10-20', '2020-10-20 20:00'], dtype='datetime64')
>>>print(a)
>>>print(a.dtype)
['2020-10-01T00:00' '2020-10-20T00:00' '2020-10-20T20:00']
datetime64[m]

可以看到,这里如果list中单位不统一,则统一用最详尽的方式表示日期(详尽效应)。

【例1-4】配合 arange 函数使用

配合arrange函数,用于生成日期范围

>>>import numpy as np
>>>a = np.arange('2020-10', '2020-11', dtype='datetime64[D]')
>>>print(a)
['2020-10-01' '2020-10-02' '2020-10-03' '2020-10-04' '2020-10-05'
 '2020-10-06' '2020-10-07' '2020-10-08' '2020-10-09' '2020-10-10'
 '2020-10-11' '2020-10-12' '2020-10-13' '2020-10-14' '2020-10-15'
 '2020-10-16' '2020-10-17' '2020-10-18' '2020-10-19' '2020-10-20'
 '2020-10-21' '2020-10-22' '2020-10-23' '2020-10-24' '2020-10-25'
 '2020-10-26' '2020-10-27' '2020-10-28' '2020-10-29' '2020-10-30'
 '2020-10-31']

同理,年-年,月-月…的用法相同,不再赘述

另外,这种方式也满足详尽效应,例如:

>>>import numpy as np
>>>a = np.arange('2020-10-01 20', '2020-10-03', dtype='datetime64')
>>>print(a)
['2020-10-01T20' '2020-10-01T21' '2020-10-01T22' '2020-10-01T23'
 '2020-10-02T00' '2020-10-02T01' '2020-10-02T02' '2020-10-02T03'
 '2020-10-02T04' '2020-10-02T05' '2020-10-02T06' '2020-10-02T07'
 '2020-10-02T08' '2020-10-02T09' '2020-10-02T10' '2020-10-02T11'
 '2020-10-02T12' '2020-10-02T13' '2020-10-02T14' '2020-10-02T15'
 '2020-10-02T16' '2020-10-02T17' '2020-10-02T18' '2020-10-02T19'
 '2020-10-02T20' '2020-10-02T21' '2020-10-02T22' '2020-10-02T23']

上述代码,h和D的datetime64变量,仍然取h进行展开

【例1-5】有趣的起始日期

>>>import numpy as np
>>>a = np.datetime64('2020-10-20', 'W')
>>>b = np.datetime64('2020-10-22', 'W')
>>>print(a, b)
2020-10-15 2020-10-22

跟【例1-2】不同的是,当用’W’去指定D类型的datetime64变量时,有如下规定:

1)如果是星期四,返回当天;
2)否则,返回上一个星期四的日期

2、关于Datetime64的运算

【例2-1】Datetime64 和 timedelta64 运算

timedelta64 表示两个 Datetime64 之间的差。timedelta64 也是带单位的,并且和相减运算中的两个 Datetime64 中的较小的单位保持一致。(详尽效应)

import numpy as np

>>>a = np.datetime64('2020-10-20') - np.datetime64('2020-10-19')
>>>b = np.datetime64('2020-10-20') - np.datetime64('2020-10-19 09:00')
>>>c = np.datetime64('2020-10-20') - np.datetime64('2020-10-18 23:00', 'D')
>>>print(a, a.dtype)
>>>print(b, b.dtype)
>>>print(c, c.dtype)

1 days timedelta64[D]
900 minutes timedelta64[m]
2 days timedelta64[D]

第三行同【例1-2】,'D’限制了天数之后的展示

下面是Datetime64 和 Timedelta64 运算:

>>>import numpy as np
>>>a = np.datetime64('2020-10') + np.timedelta64(20, 'D')
>>>print(a,a.dtype)
2020-10-21 datetime64[D]

【例2-2】timedelta64 单独运算

import numpy as np

#单独生成timedelta64
>>>a = np.timedelta64(1, 'Y')    # 方式一
>>>b = np.timedelta64(a, 'M')    # 方式二
>>>print(a)
>>>print(b)
1 years
12 months

#timedelta64加减乘除
>>>a = np.timedelta64(2, 'Y')
>>>b = np.timedelta64(5, 'M')
>>>print(a + b)
>>>print(a - b)
>>>print(2 * a)
>>>print(a / b)
29 months
19 months
4 years
4.8

年(‘Y’)和月(‘M’)这两个单位是经过特殊处理的,它们无法和其他单位进行运算,一年有几天?一个月有几天?这些都是不确定的,比如:

>>>import numpy as np
>>>a = np.timedelta64(1, 'M')
>>>b = np.timedelta64(a, 'D')
TypeError: Cannot cast NumPy timedelta64 scalar from metadata [M] to [D] according to the rule 'same_kind'

【例2-3】numpy.datetime64 与 datetime.datetime 相互转换

datetime 模块是python中提供用于处理日期和时间的类。

在支持日期时间数学运算的同时,实现的关注点更着重于如何能够更有效地解析其属性用于格式化输出和数据操作。

>>>import numpy as np
>>>import datetime

>>>dt = datetime.datetime(2020, 10, 20)
>>>dt64 = np.datetime64(dt, 'D')
>>>print(dt64, dt64.dtype)

>>>dt2 = dt64.astype(datetime.datetime)
>>>print(dt2,type(dt2))
2020-10-20 datetime64[D]
2020-10-20 <class 'datetime.date'>

可以看到,我们可以直接用np.datetime64(datetime,dtype)来实现从后者到前者的转换,另外,我们可以通过datetime64.astype(datetime.datetime)实现从前者到后者的转换

3、工作日功能

为了允许在只有一周中某些日子有效的上下文中使用日期时间,NumPy包含一组“busday”(工作日)功能。

将指定的偏移量(offsets)应用于工作日,单位天(‘D’),偏移量为正表示朝着日历向后的方向

【例3-1】返回指定日期是否是工作日

import numpy as np

# 2020-10-20 星期二
>>>a = np.is_busday('2020-10-18')
>>>b = np.is_busday('2020-10-20')
>>>print(a)  
>>>print(b)  

False
True

【例3-2】返回下n个工作日

import numpy as np

# 2020-07-10 星期五
>>>a = np.busday_offset('2020-10-20', offsets=1)
>>>print(a)  # 2020-07-13
2020-10-21

>>>a = np.busday_offset('2020-10-20', offsets=2)
>>>print(a)
2020-10-22

>>>a = np.busday_offset('2020-10-18', offsets=2)
>>>print(a)
ValueError: Non-business day date in busday_offset


>>>a = np.busday_offset('2020-10-18', offsets=0, roll='forward')
>>>b = np.busday_offset('2020-10-18', offsets=0, roll='backward')
>>>print(a) 
>>>print(b) 
2020-10-19
2020-10-16

>>>a = np.busday_offset('2020-10-18', offsets=1, roll='forward')
>>>b = np.busday_offset('2020-10-18', offsets=1, roll='backward')
>>>print(a)  
>>>print(b)  
2020-10-20
2020-10-19

可以指定偏移量为 0 来获取当前日期向前或向后最近的工作日,当然,如果当前日期本身就是工作日,则直接返回当前日期。如果当前日期为非工作日,默认报错。可以指定 forward backward 规则来避免报错。
(注:forward指的是日历向后,backward指的是日历向前,如果从字面意思容易弄混)

小技巧:第一步先判断当天是否有工作日,若是则进行偏移;若不是,则需要根据

【例3-3】统计一个 datetime64[D] 数组中的工作日天数。

import numpy as np

# 2020-10-20 星期二
>>>begindates = np.datetime64('2020-10-20')
>>>enddates = np.datetime64('2020-11-01')
>>>a = np.arange(begindates, enddates, dtype='datetime64')
>>>b = np.count_nonzero(np.is_busday(a))
>>>c = np.busday_count(begindates, enddates)
>>>print(a)
>>>print(b)
>>>print(c)

['2020-10-20' '2020-10-21' '2020-10-22' '2020-10-23' '2020-10-24'
 '2020-10-25' '2020-10-26' '2020-10-27' '2020-10-28' '2020-10-29'
 '2020-10-30' '2020-10-31']
9

a和b的组合效果等于c,都是在计算一段日期范围的工作日天数,且前闭后开

【例3-4】自定义周掩码值,即指定一周中哪些星期是工作日。

import numpy as np

# 2020-10-20 星期二
>>>a = np.is_busday('2020-10-20', weekmask=[1, 0, 1, 0, 1, 0, 1])
>>>b = np.is_busday('2020-10-20', weekmask='0100000')
>>>c = np.is_busday('2020-10-20', weekmask='Tue')
>>>print(a)  
>>>print(b)  
>>>print(c)
False
True
True

如上,weekmask一共有三种设置方式,这里需要注意的是系统默认与真实世界的日历一一对应,即1970-01-01为星期四,是不是很有趣呢

文章来源互联网,如有侵权,请联系管理员删除。邮箱:417803890@qq.com / QQ:417803890

微配音

Python Free

邮箱:417803890@qq.com
QQ:417803890

皖ICP备19001818号
© 2019 copyright www.pythonf.cn - All rights reserved

微信扫一扫关注公众号:

联系方式

Python Free