Spec-Zone.ru › NumPy 1.19

Даты и временные интервалы

Новое в версии 1.7.0.

Начиная с NumPy 1.7, существуют базовые типы данных массивов, которые изначально поддерживают функциональность работы с датами и временем. Тип данных называется «datetime64», так как «datetime» уже используется в стандартной библиотеке Python.

Примечание

API для работы с датами и временем в версии 1.7.0 находится на стадии экспериментальной разработки и может быть изменён в будущих версиях NumPy.

Основные даты и время

Самый простой способ создания дат и времени — из строк в формате даты или времени ISO 8601. Единица измерения для внутреннего хранения автоматически выбирается из формата строки и может быть либо единицей измерения даты, либо единицей измерения времени. Единицы измерения дат — годы (‘Y’), месяцы (‘M’), недели (‘W’) и дни (‘D’), а единицы измерения времени — часы (‘h’), минуты (‘m’), секунды (‘s’), миллисекунды (‘ms’), и некоторые дополнительные единицы измерения времени, основанные на секундах с использованием префиксов СИ. Тип данных datetime64 также принимает строку «NAT» (в любом сочетании строчных/прописных букв) для значения «Нет времени».

Пример

Простая дата в формате ISO:

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

Использование месяцев как единицы измерения:

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

Указание только месяца, но принудительное использование единицы ‘days’:

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

Из даты и времени:

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

NAT (нет времени):

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

При создании массива дат и времени из строки по-прежнему можно автоматически выбрать единицу измерения из входных данных, используя тип datetime с общими единицами.

Пример

>>> 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 позволяет вычитать две даты и время, операция, которая производит число с единицей измерения времени. Поскольку NumPy не имеет системы физических величин в своём ядре, был создан тип данных timedelta64, дополняющий datetime64. Аргументы для timedelta64 — это число, представляющее количество единиц, и единица измерения даты/времени, такая как (D) день, (M) месяц, (Y) год, (h) часы, (m) минуты или (s) секунды. Тип данных timedelta64 также принимает строку «NAT» вместо числа для значения «Нет времени».

Пример

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

Даты и временные интервалы работают вместе, чтобы обеспечить способы для простых вычислений дат и времени.

Пример

>>> 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')

Существуют две единицы измерения Timedelta (‘Y’, годы и ‘M’, месяцы), которые обрабатываются особенно, потому что то, сколько времени они представляют, меняется в зависимости от того, где они используются. В то время как единица измерения 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'

Единицы измерения дат

Типы данных Datetime и Timedelta поддерживают большое количество единиц измерения времени, а также общие единицы, которые могут быть приведены к любой другой единице на основе входных данных.

Даты и время всегда хранятся на основе времени POSIX (хотя предлагается режим TAI, который позволяет учитывать високосные секунды), с эпохой 1970-01-01T00:00Z. Это означает, что поддерживаемые даты всегда являются симметричным интервалом вокруг эпохи, называемым «временным интервалом» в таблице ниже.

Длина интервала — это диапазон 64-битного целого числа, умноженный на длину даты или единицы. Например, временной интервал для ‘W’ (неделя) в точности в 7 раз больше, чем временной интервал для ‘D’ (день), а временной интервал для ‘D’ (день) в точности в 24 раза больше, чем временной интервал для ‘h’ (час).

Вот единицы измерения дат:

Код

Значение

Временной интервал (относительно)

Временной интервал (абсолютно)

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 н.э.]

m

минута

+/- 1.7e13 лет

[1.7e13 до н.э., 1.7e13 н.э.]

s

секунда

+/- 2.9e11 лет

[2.9e11 до н.э., 2.9e11 н.э.]

ms

миллисекунда

+/- 2.9e8 лет

[ 2.9e8 до н.э., 2.9e8 н.э.]

us

микросекунда

+/- 2.9e5 лет

[290301 до н.э., 294241 н.э.]

ns

наносекунда

+/- 292 года

[ 1678 н.э., 2262 н.э.]

ps

пикосекунда

+/- 106 дней

[ 1969 н.э., 1970 н.э.]

fs

фемтосекунда

+/- 2.6 часа

[ 1969 н.э., 1970 н.э.]

as

аттосекунда

+/- 9.2 секунды

[ 1969 н.э., 1970 н.э.]

Функциональность рабочих дней

Для того, чтобы позволить использовать дату и время в контекстах, где допустимы только определённые дни недели, NumPy включает набор функций «busday» (рабочие дни).

По умолчанию для функций busday допустимыми днями являются понедельник по пятницу (обычные рабочие дни). Реализация основана на «weekmask», содержащем 7 булевых флагов, чтобы указать допустимые дни; возможны пользовательские 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 сначала применяет правило для сдвига даты на допустимый рабочий день, а затем применяет сдвиг. Правило по умолчанию — ‘raise’, которое просто генерирует исключение. Наиболее часто используемые правила — ‘forward’ и ‘backward’.

Пример

>>> 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')

Функция также полезна для вычисления некоторых типов дней, таких как праздничные дни. В Канаде и США День матери приходится на второе воскресенье мая, что можно вычислить с помощью пользовательского weekmask.

Пример

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

Когда производительность важна для обработки многих рабочих дат с определённым выбором weekmask и праздничных дней, существует объект busdaycalendar, который хранит необходимые данные в оптимизированной форме.

np.is_busday():

Для проверки значения 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])

np.busday_count():

Чтобы найти количество допустимых дней в указанном диапазоне дат datetime64, используйте 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

Ниже приведены несколько примеров значений 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"

© 2005–2020 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.19/reference/arrays.datetime.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API