日期时间和时间增量

1.7.0 新版功能.

从numpy 1.7开始,有一些核心数组数据类型本机支持datetime功能。数据类型称为“datetime64”,之所以这样命名是因为“datetime”已经被包含在python中的datetime库占用。

注解

日期时间API是 实验的 在1.7.0中,可能会在未来版本的numpy中发生更改。

基本日期

创建日期时间的最基本方法是使用ISO 8601日期或日期时间格式的字符串。内部存储单元是从字符串的形式中自动选择的,可以是 date unit 或A time unit . 时间单位为“M”,时间单位为“M”,时间单位为“s”,时间单位为“M”,时间单位为“s”,时间单位为“s”,时间单位为“M”,时间单位为“s”,时间单位为“M”,时间单位为“s”,时间单位为“M”,时间单位为“s”,时间单位为“s”,时间单位为“M”,时间单位为“s”,时间单位为“M”,时间单位为“s”,时间单位为“s”,时间单位为。datetime64数据类型还接受字符串“NAT”(小写/大写字母的任意组合)作为“Not a Time”值。

例子

简单的ISO日期:

>>> np.datetime64('2005-02-25')
numpy.datetime64('2005-02-25')

单位使用月数:

>>> np.datetime64('2005-02')
numpy.datetime64('2005-02')

仅指定月份,但强制使用“天”单位:

>>> np.datetime64('2005-02', 'D')
numpy.datetime64('2005-02-01')

开始日期和时间:

>>> np.datetime64('2005-02-25T03:30')
numpy.datetime64('2005-02-25T03:30')

纳特(不是时候):

>>> np.datetime64('nat')
numpy.datetime64('NaT')

从字符串创建日期时间数组时,仍然可以通过使用带通用单位的日期时间类型从输入中自动选择单位。

例子

>>> np.array(['2007-07-13', '2006-01-13', '2010-08-13'], dtype='datetime64')
array(['2007-07-13', '2006-01-13', '2010-08-13'], dtype='datetime64[D]')
>>> np.array(['2001-01-01T12:00', '2002-02-03T13:56:03.172'], dtype='datetime64')
array(['2001-01-01T12:00:00.000', '2002-02-03T13:56:03.172'],
      dtype='datetime64[ms]')

例如,datetime类型与许多常见的numpy函数一起使用。 arange 可用于生成日期范围。

例子

一个月的所有日期:

>>> np.arange('2005-02', '2005-03', dtype='datetime64[D]')
array(['2005-02-01', '2005-02-02', '2005-02-03', '2005-02-04',
       '2005-02-05', '2005-02-06', '2005-02-07', '2005-02-08',
       '2005-02-09', '2005-02-10', '2005-02-11', '2005-02-12',
       '2005-02-13', '2005-02-14', '2005-02-15', '2005-02-16',
       '2005-02-17', '2005-02-18', '2005-02-19', '2005-02-20',
       '2005-02-21', '2005-02-22', '2005-02-23', '2005-02-24',
       '2005-02-25', '2005-02-26', '2005-02-27', '2005-02-28'],
      dtype='datetime64[D]')

datetime对象表示一个时间点。如果两个日期时间具有不同的单位,它们可能仍然代表相同的时间时刻,并且从较大的单位(如月)转换为较小的单位(如天)被认为是“安全”的投射,因为时间时刻仍被准确地表示。

例子

>>> np.datetime64('2005') == np.datetime64('2005-01-01')
True
>>> np.datetime64('2010-03-14T15') == np.datetime64('2010-03-14T15:00:00.00')
True

1.11.0 版后已移除: NumPy不存储时区信息。为了向后兼容,datetime64仍然解析时区偏移量,它通过转换为UTC来处理。此行为已被弃用,并将在将来引发错误。

日期时间和时间增量算法

NumPy允许两个Datetime值相减,这是一种产生一个以时间为单位的数字的操作。因为NumPy的核心没有物理量系统,所以创建timedelta64数据类型是为了补充datetime64。timedelta64的参数是一个表示单位数的数字,以及一个日期/时间单位,例如(D)ay、(M)onth、(Y)ear、(h)ours、(M)inutes或(s)econds。timedelta64数据类型还接受字符串“NAT”来代替“Not a Time”值的数字。

例子

>>> np.timedelta64(1, 'D')
numpy.timedelta64(1,'D')
>>> np.timedelta64(4, 'h')
numpy.timedelta64(4,'h')
>>> np.timedelta64('nAt')
numpy.timedelta64('NaT')

datetime和timedelta一起工作,为简单的datetime计算提供方法。

例子

>>> np.datetime64('2009-01-01') - np.datetime64('2008-01-01')
numpy.timedelta64(366,'D')
>>> np.datetime64('2009') + np.timedelta64(20, 'D')
numpy.datetime64('2009-01-21')
>>> np.datetime64('2011-06-15T00:00') + np.timedelta64(12, 'h')
numpy.datetime64('2011-06-15T12:00')
>>> np.timedelta64(1,'W') / np.timedelta64(1,'D')
7.0
>>> np.timedelta64(1,'W') % np.timedelta64(10,'D')
numpy.timedelta64(7,'D')
>>> np.datetime64('nat') - np.datetime64('2009-01-01')
numpy.timedelta64('NaT','D')
>>> np.datetime64('2009-01-01') + np.timedelta64('nat')
numpy.datetime64('NaT')

有两个时间增量单位(“y”、“years”和“m”、months),它们都经过特殊处理,因为它们代表的时间长短取决于使用时间。虽然TimeDelta日单位等于24小时,但无法将月单位转换为天,因为不同的月份具有不同的天数。

例子

>>> a = np.timedelta64(1, 'Y')
>>> np.timedelta64(a, 'M')
numpy.timedelta64(12,'M')
>>> np.timedelta64(a, 'D')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Cannot cast NumPy timedelta64 scalar from metadata [Y] to [D] according to the rule 'same_kind'

日期时间单位

日期时间和时间增量数据类型支持大量的时间单位,以及可以根据输入数据强制转换为任何其他单位的通用单位。

日期时间总是基于posix时间存储的(尽管建议使用允许计算闰秒的tai模式),其历元为1970-01-01t00:00z。这意味着支持的日期总是围绕历元的对称间隔,在下表中称为“时间跨度”。

跨度的长度是64位整数乘以日期或单位的长度的范围。例如,“w”(周)的时间跨度正好比“d”(日)的时间跨度长7倍,“d”(日)的时间跨度正好比“h”(小时)的时间跨度长24倍。

以下是日期单位:

代码

意义

时间跨度(相对)

时间跨度(绝对)

Y

+/-9.2E18年

[公元前9.2E18年,公元前9.2E18年]

M

+/-7.6e17年

[公元前7.6e17,公元前7.6e17]

W

+/-1.7e17年

[公元前1.7e17年,公元前1.7e17年]

D

白天

+/-2.5e16年

[公元前2.5e16年,公元2.5e16年]

以下是时间单位:

代码

意义

时间跨度(相对)

时间跨度(绝对)

H

小时

+/-1.0e15年

[公元前1.0e15年,公元前1.0e15年]

分钟

+/-1.7e13年

[公元前1.7e13年,公元前1.7e13年]

S

第二

+/-2.9e11年

[公元前2.9e11年,公元2.9e11年]

毫秒

毫秒

+/-2.9E8年

[公元前2.9E8年,公元2.9E8年]

us/微秒

微秒

+/-2.9E5年

[公元前290301年,公元294241年]

纳秒

毫微秒

+/- 292年

[公元1678年,公元2262年]

聚苯乙烯

皮秒

+/- 106天

[公元1969年,公元1970年]

FS

飞秒

+/- 2.6小时

[公元1969年,公元1970年]

作为

阿秒

+/- 9.2秒

[公元1969年,公元1970年]

工作日功能

为了允许在只有一周中特定日期有效的上下文中使用日期时间,numpy包含一组“busday”(工作日)函数。

BusDay函数的默认值是,唯一有效的日期是星期一到星期五(通常的工作日)。实现基于包含7个布尔标志的“weekmask”来指示有效日期;自定义weekmask可以指定其他有效日期集。

“busday”功能还可以检查“holiday”日期、无效日期的特定日期列表。

函数 busday_offset 允许您将工作日中指定的偏移量应用于日期时间,单位为“d”(天)。

例子

>>> np.busday_offset('2011-06-23', 1)
numpy.datetime64('2011-06-24')
>>> np.busday_offset('2011-06-23', 2)
numpy.datetime64('2011-06-27')

当输入日期在周末或假日时, busday_offset 首先应用规则将日期滚动到有效的工作日,然后应用偏移量。默认规则是“引发”,这只会引发异常。最常用的规则是“向前”和“向后”。

例子

>>> np.busday_offset('2011-06-25', 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Non-business day date in busday_offset
>>> np.busday_offset('2011-06-25', 0, roll='forward')
numpy.datetime64('2011-06-27')
>>> np.busday_offset('2011-06-25', 2, roll='forward')
numpy.datetime64('2011-06-29')
>>> np.busday_offset('2011-06-25', 0, roll='backward')
numpy.datetime64('2011-06-24')
>>> np.busday_offset('2011-06-25', 2, roll='backward')
numpy.datetime64('2011-06-28')

在某些情况下,需要适当地使用辊和偏移量来获得所需的答案。

例子

日期或之后的第一个工作日:

>>> np.busday_offset('2011-03-20', 0, roll='forward')
numpy.datetime64('2011-03-21')
>>> np.busday_offset('2011-03-22', 0, roll='forward')
numpy.datetime64('2011-03-22')

日期后的第一个工作日:

>>> np.busday_offset('2011-03-20', 1, roll='backward')
numpy.datetime64('2011-03-21')
>>> np.busday_offset('2011-03-22', 1, roll='backward')
numpy.datetime64('2011-03-23')

该函数还可用于计算某些类型的日期,如节假日。在加拿大和美国,母亲节是在5月的第二个星期日,可以用自定义的周掩码计算。

例子

>>> np.busday_offset('2012-05', 1, roll='forward', weekmask='Sun')
numpy.datetime64('2012-05-13')

当性能对于使用一个特定的weekmask和holidays选项操纵多个业务日期很重要时,有一个对象 busdaycalendar 它以优化的形式存储必要的数据。

iS.BayDay.():

要测试datetime64值以查看它是否为有效日期,请使用 is_busday .

例子

>>> np.is_busday(np.datetime64('2011-07-15'))  # a Friday
True
>>> np.is_busday(np.datetime64('2011-07-16')) # a Saturday
False
>>> np.is_busday(np.datetime64('2011-07-16'), weekmask="Sat Sun")
True
>>> a = np.arange(np.datetime64('2011-07-11'), np.datetime64('2011-07-18'))
>>> np.is_busday(a)
array([ True,  True,  True,  True,  True, False, False])

busday_count():

要查找指定日期范围内的有效天数,请使用 busday_count

例子

>>> np.busday_count(np.datetime64('2011-07-11'), np.datetime64('2011-07-18'))
5
>>> np.busday_count(np.datetime64('2011-07-18'), np.datetime64('2011-07-11'))
-5

如果您有一个datetime64天值数组,并且您想要一个有效日期的计数,那么您可以这样做:

例子

>>> a = np.arange(np.datetime64('2011-07-11'), np.datetime64('2011-07-18'))
>>> np.count_nonzero(np.is_busday(a))
5

自定义周掩码

下面是几个自定义weekmask值的示例。这些示例指定周一到周五的“busday”默认值为有效天数。

一些例子:

# Positional sequences; positions are Monday through Sunday.
# Length of the sequence must be exactly 7.
weekmask = [1, 1, 1, 1, 1, 0, 0]
# list or other sequence; 0 == invalid day, 1 == valid day
weekmask = "1111100"
# string '0' == invalid day, '1' == valid day

# string abbreviations from this list: Mon Tue Wed Thu Fri Sat Sun
weekmask = "Mon Tue Wed Thu Fri"
# any amount of whitespace is allowed; abbreviations are case-sensitive.
weekmask = "MonTue Wed  Thu\tFri"