Рубрики
Без рубрики

Numpy DateTime: Как работать с датами и временем в Python?

Полное учебное пособие np.dateTime64. Все, что вам нужно знать, чтобы начать …

Автор оригинала: Adam Murphy.

В этой статье мы узнаем о чем-то, что буквально везде. Какой бы угол вы поворачиваетесь, какая бы улица вы бежали, вы не можете уйти от него. Это как повсеместно, как физическое пространство вокруг нас. Да сегодня мы говорим о … время. Более конкретно, мы говорим о Функции Numpy, которые представляют даты и времена Отказ

Упражнение : Создайте объекты Numpy DateTime от вашего дня рождения! Теперь рассчитайте количество дней, которые прошли с тех пор.

Когда я впервые услышал о Numpy’s datetime Библиотека, я не думал, что это было большое дело. Почему нам нужны специальные функции, чтобы иметь дело с датами? Они довольно просты, не можем просто использовать строки, такие как '2019/01/01' И сделать с этим?

Ну, молодая версия меня, оказывается, они довольно сложны, и мы не можем «просто использовать строки» …

Если вы не уверены, попробуйте ответить на любой из следующих вопросов, используя «просто строки»:

  1. Сколько дней в месяце?
  2. Сколько секунд между 1 марта 2019 года в 13:00 и 4 марта 2019 года на 2 утра именно?
  3. Сколько рабочих дней находятся между 1 января 1970 года (эпоха Unix) и 3 декабря 2008 года (день Python 3 был освобожден)?

Очевидно, нам нужны даты и времена, чтобы иметь свои собственные функции. И не волнуйтесь, мы ответим на все эти вопросы к концу статьи.

Вы хотите стать Numpy Master? Проверьте нашу интерактивную книгу головоломки Coffe Break Numpy И повысить свои навыки науки о данных! (Ссылка Amazon открывается на новой вкладке.)

Нежное введение

Хотя мы не можем «просто использовать Строки «Представлять даты и времена, мы будем использовать строки в качестве ввода к основной функции, с которой мы будем работать: np.dateTime64 () Отказ

Примечание : то 64 означает, что цифры 64 бита.

Numpy использует сокращения следующих (здравых смыслов) для единиц времени, обратите внимание на капитализацию, где это происходит:

Годы Y
Месяцы M
Недели W
Дни D
Часы h
Минут m
Секунды s
Миллисекунды РС
Microconds (поскольку μs (греческая буква «MU») так, как мы передаем ее, и «U» выглядит ближе всего к этому на английском языке). нас

Формат ввода – ISO 8601

Разные страны пишут своими даты по-разному. В Европе 06/10/18 – 6 октября, а в Америке 10 июня. Лично, это может быть раздражает, но в бизнесе, это критично (представьте, что ваша программа работает до 6 октября, когда вы хотели, чтобы она остановилась 10 июня)! Итак, нам нужен стандартизированный вход для наших функций. К счастью, глобальный стандарт уже существует ISO 8601 Отказ

Основы:

  • Yyyy-mm-dd Для дат, так 2018-10-06 6 октября 2018 года
  • HH: мм: SS Время, так 13:21:40 13:21 (13,21 вечера) и 40 секунд
  • Для миллисекунды используйте полный стоп, 13: 21: 40.3 (Добавление 3 миллисекунды).

Это легко вспомнить, как даты и времена идут налево, направо от большого до маленького. Это будет важно позже, когда мы сделаем арифметику с datetime объекты.

Чтобы ввести это на Numpy, мы можем либо

  • Поместите пространство между датой и временем '2019-10-23 13:21' '
  • Или поставить столицу T между ними '2019-10-21T13: 21'

Я предпочитаю первый метод, так как легче читать. Но обратите внимание, что если вы распечатаете любой np.dateTime64 Функции, Numpy всегда вставляют T Отказ

Теперь пришло время для наших первых примеров (я пытался выбрать даты, которые легко читать для обучения).

# 2000
>>> np.datetime64('2000')
 
# November 2000
>>> np.datetime64('2000-11')
 
# 22nd November 2000
>>> np.datetime64('2000-11-22')
 
# 7th June 1987 at 16:22:44 (twenty two minutes past four in the afternoon and forty four seconds)
>>> np.datetime64('2000-11-22 16:22:44')
numpy.datetime64('2000-11-22T16:22:44')

Рекантралирование

Учитывая конкретное значение dateTime, вы можете изменить его в определенный момент времени, введя его в качестве второго параметра.

Например, скажем, у нас есть определенный день, но только хочу месяц:

# 22nd November 2000
>>> day = np.datetime64('2000-11-22')
 
# Just keep the month
>>> month = np.datetime64(day, 'M')
numpy.datetime64('2000-11')
 
# Change the scale of month to hours
>>> hour_from_month = np.datetime64(month, 'h')
numpy.datetime64('2000-11-01T00','h')
 
# Change the scale of day to hours
>>> hour_from_day = np.datetime64(day, 'h')
numpy.datetime64('2000-11-22T00','h')

Обратите внимание, что часть DD для HOURE_FROM_MONH и HOURE_FROM_DAY разные. Первый имеет 01 и последний 22. Это потому, что numpy возвращается к значениям по умолчанию, если никто не указан. Это логически, 01 для M и D и 0 для переменных времени.

Чтобы проверить единицу времени np.dateTime64 объект, мы просто используем .dtype атрибут:

>>> day.dtype
dtype('>> month.dtype
dtype('

Легко.

Арифметика DateTime

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

Что наступает дальше после 12 вечера 12 декабря 1999 года?

В зависимости от единицы времени вы рассчитываете, это может быть что-нибудь:

  • Подсчет вперед в часах: 1 вечера 12 декабря 1999 года
  • Подсчет назад в дни: 12 вечера 11 декабря 1999 года
  • Подсчет вперед в годы: 12 декабря 2000 г.

Вы получаете идею.

Как мы уже видели, каждый np.dateTime64 Объект имеет единицу времени, связанный с ним. Поэтому, если мы ‘+ 5’ на наш объект «день», мы пойдем вперед 5 дней. И если мы ‘- 5’ с нашего месяца объекта, мы пойдем назад 5 месяцев:

# 22nd November 2000 + 5 days
>>> day + 5
numpy.datetime64('2000-11-27')
 
# November 2000 - 5 months
>>> month - 5
numpy.datetime64('2000-06')

Но что, если мы хотим посмотреть на Рождественский день каждый год за последние 50 лет? Мы не можем начать с 2018-12-25 и «- 1», потому что это прилагает временную единицу «D», и поэтому дает нам 2018-12-24.

Numpy решил эту проблему, введя другую функцию с помощью прохладной фамилии: np.timedelta64 Отказ

np.timedelta64.

Любая арифметика, которая сложнее, чем добавление или вычитание целые числа включает в себя np.timedelta64 Отказ Уравнение либо вернет np.timedelta64 объект или вам нужно будет использовать один, чтобы получить результат.

Если вы все поняли до этого момента, вы легко поймете это. Это лучше всего объяснено в примерах.

Количество дней с 1 января 2013 года и 1 января 2012 года 366, так как это был скачок года.

>>> np.datetime64('2013-01-01') - np.datetime64('2012-01-01')
numpy.timedelta64(366,'D')
 
# Add on 15 days to June 2000
>>> np.datetime64('2000-05') + np.timedelta64(15, 'D')
numpy.datetime64('2000-05-16')
 
# What is 5 hours after 1pm on 22nd Nov 2000?
>>> np.datetime64('2000-11-22 13:00') + np.timedelta64(5, 'h')
numpy.datetime64('2000-11-22T18:00')

Каждый np.timedelta64 () Объект принимает одно целое и однократное устройство. Таким образом, чтобы добавить через 4 месяца и 3 дня, у вас есть два варианта.

Первый – использовать два экземпляра np.timedelta64 :

# Add on 4 months and 3 days
>>> some_date + np.timedelta64(4, 'M') + np.timedelta64(3, 'D')

Второе – преобразовать отдельный np.timedelta64 объекты в один с использованием разделения (или модуло):

# 1 day is 24 hours
>>> np.timedelta64(1, 'D') / np.timedelta64(1, 'h')
24.0
 
# 1 week is 10,080 minutes
>>> np.timedelta64(1, 'W') / np.timedelta64(1, 'm')
10080.0
 
# 1 month is ??? days
>>> np.timedelta64(1, 'M') / np.timedelta64(1, 'D')
TypeError: Cannot get a common metadata divisor for NumPy datetime metadata [M] and [D] because they have incompatible nonlinear base time units

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

Большинство людей согласились бы, что через месяц после 31 января 28 февраля. Но что через месяц после 28 февраля? 28 марта или 31 марта? Так что numpy бросает ошибку, если вы попытаетесь изменить месяц/год np.dateTime64 объект со временным устройством 'D' или меньше.

# Both work because time unit is 'M'
 
# Add 1 month
>>> np.datetime64('2000-02') + np.timedelta64(1, 'M')
numpy.datetime64('2000-03')
 
# Add 1 year
>>> np.datetime64('2000-02') + np.timedelta64(1, 'Y')
numpy.datetime64('2001-02')

Как только мы получим более точные, значения месяца и года не являются постоянными, а Numpy бросает ошибку.

# Neither work because time unit is 'D'
 
# Add 1 month
>>> np.datetime64('2000-02-01') + np.timedelta64(1, 'M')
TypeError: ...
 
# Add 1 year
>>> np.datetime64('2000-02-01') + np.timedelta64(1, 'Y')
TypeError: ...

Мы теперь оснащены, чтобы построить список любых дат и времена нашего сердца! Итак, давайте построим один, содержащий все рождественские дни за последние 50 лет. Мы начнем с последних декабря. 2018-12 и повторяйте через него 50 раз назад. Для первой итерации мы вычвеем один год (чтобы получить 2017 год), для второго мы вычитаем 2 года (чтобы получить 2016 год) и так далее. Наконец, в каждой итерации мы добавляем 24 дня (поскольку день по умолчанию 01). Мы сделаем все это, используя один из наиболее любимых аспектов Python: понимание списка!

# Start with 2018-12
>>> all_christmas_days = [np.datetime64('2018-12') \
                          - np.timedelta64(i, 'Y') \
                          + np.timedelta64(24, 'D')
                          for i in range(50)]
 
# Contains 50 years
>>> len(all_christmas_days)
50
 
# First 3 years
>>> all_christmas_days[:3]
[numpy.datetime64('2018-12-25'),
 numpy.datetime64('2017-12-25'),
 numpy.datetime64('2016-12-25')]
 
# Last 3 years (we start counting at -1 and the end index is excluded)
>>> all_christmas_days[:-4:-1]
[numpy.datetime64('1969-12-25'),
 numpy.datetime64('1970-12-25'),
 numpy.datetime64('1971-12-25')]

Теперь мы знаем ответы на вопросы 1 и 2, которые я спросил в начале.

  1. Сколько дней в месяце?
    • Неопределенный. Это может быть 28, 30 или 31 … Это приведет к вопросам, если ваши единицы времени являются «D» или меньше.
  2. Сколько секунд между 1 марта 2019 года в 13:00 и 4 марта 2019 года на 2 утра именно?
    • 219 600с.
# Subtract both dates written with time unit 's'
>>> np.datetime64('2019-03-04 02:00:00') \
  - np.datetime64('2019-03-01 13:00:00')
 
numpy.timedelta64(219600,'s')

Но как насчет вопроса 3? Это было о рабочих днях, поэтому давайте узнаем о них сейчас.

Сколько рабочих дней между двумя днями?

Мы можем создать любой список данных DateTimes, используя инструменты выше. Но есть несколько вещей, которые мы можем использовать, чтобы упростить нашу жизнь.

Предприятия обычно заботятся только о том, что происходит в своих дни операции. Поэтому было бы неплохо иметь набор функций для решения этого. Было бы много ненужных точек данных, если бы нам пришлось включить субботу и воскресенье в анализе данных на акции.

К счастью, Numpy обрабатывает это, используя концепцию рабочих дней с np.busday () функция.

Есть несколько из них, и объяснить их все подробно, это еще один блог по себе. Итак, я сосредоточу на самых важных, чтобы присоединиться и бежать: np.is_busday () , np.busday_count () и np.busday_offset () Отказ

Но во-первых, нам нужно покрыть всеобъемлющую концепцию.

Недели

Центральная к этим функциям является ключевым словом «Weekmass». Эта переменная определяет, какие дни считаются рабочими днями.

Следующие еженедельники все установили рабочие дни в понедельник, вторник, среду, четверг и пятницу (поведение по умолчанию):

weekmask_names = 'Mon Tue Wed Thu Fri'
weekmask_string = '1111100'
weekmask_list = [1, 1, 1, 1, 1, 0, 0]
  • Weekmass_Names – писать заглавные, трехбуквенные сокращения (пн, вт, ср, чт, пт, сел, солнце). Whitespace игнорируется.
  • Weekmask_String – строка длины 7 где «1» день и «0′-рабочий день» (начиная с пн)
  • Weekmask_List – список длин 7, где 1 день и 0 рабочих дней (начиная с пн)

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

Примечание: вход в np.busday Функции не строка, а скорее np.dateTime64 () объект.

np.is_busday ()

Возвращает логическое значение: Правда Если день это рабочий день, Ложь Если это не так.

# Wednesday 23rd October 2019
>>> np.is_busday(np.datetime64('2019-10-23'))
True
 
# Saturday 19th October 2019
>>> np.is_busday(np.datetime64('2019-10-19'))
False
 
# Saturday 19th October 2019 with Saturday classed as a business
# day in addition to Mon-Fri
>>> np.is_busday(np.datetime64('2019-10-19'), weekmask='1111110')
True

Примечание. Вы можете использовать эту функциональность для создания списков любого определенного дня. Просто установите Weekmask в интересные дни и используйте np.is_busday (), чтобы выбрать соответствующие.

# Create Wed and Sat boolean array (True if day is Wed or Sat)
>>> wed_sat_mask = np.is_busday(list_of_dates, weekmast='Wed Sat')
 
# Filter list to return just Wed and Sat
>>> only_wed_sat = list_of_dates[wed_sat_mask]

np.busday_count ()

Возвращает количество рабочих дней между двумя датами, которые вы предоставляете.

Теперь мы можем ответить на вопрос 3:

  1. Сколько рабочих дней находятся между 1 января 1970 года (эпоха Unix) и 3 декабря 2008 года (день Python 3 был освобожден)?
    • 10 154 дней
>>> np.busday_count('1970-01-01', '2008-12-03')
10154

np.busday_offset ()

Возвращает действующий рабочий день в соответствии с правилом ролика и количество дней для компенсации.

Мы будем использовать это, чтобы найти ближайший рабочий день для любой даты, которую мы передаем к этой функции.

Например, мы хотим найти цену фондового рынка 18 мая 2019 года. Это невозможно, так как это в субботу, а фондовый рынок закрыт. Мы будем использовать эту функцию, чтобы получить np.dateTime64 объект ближе всего к нему это рабочий день.

Аргументы: np.dateTime64 объект, количество дней для компенсации и «рулон». Мы просто будем использовать (то есть нет компенсации), чтобы найти ближайший рабочий день .. и мы установим. Таким образом, если мы введем субботу, он должен вернуться в понедельник. Если мы используем, мы получим пятницу (за день до субботы).

Для простоты мы проигнорируем более сложные случаи использования. Пожалуйста, обратитесь к Документация Если вы хотите более подробные объяснения.

# Saturday 18th May 2019
>>> sat_may_18 = np.datetime64('2019-05-18')
 
# Closest business day forwards in time is Monday 20th May 2019
>>> np.busday_offset(sat_may_18, 0, roll='forward')
numpy.datetime64('2019-05-20')
 
# Closest business day back in time is Friday 17th May 2019
>>> np.busday_offset(sat_may_18, 0, roll='backward')
numpy.datetime64('2019-05-17')

np.dateTime64 с np.arange.

Последнее, что мы посмотрим на создание даты, даже проще сочетают его с функцией NP.Arge.

Помните, что аргументы для NP.Arge почти идентичны встроенному Диапазон () функция. Но есть добавленная 'dtype' Аргумент ключевых слов, чья по умолчанию нет. Как ассортимент, остановка в NP.Arange является эксклюзивным и поэтому не включена в расчет.

np.arange(start, stop, step, dtype=None)

Хотите понять функцию Numpy Arange () один раз и для всех? Читайте моего руководства в блоге: Окончательное руководство по NP.Arge () с видео.

При работе с DateTimes вы должны включить дату начала и остановки и установить DTYPE.

# All days in 2017
>>> days_2017 = np.arange('2017-01-01', '2018-01-01', 
                           dtype='datetime64[D]')
 
# Every other day in 2017
>>> days_step_2_2017 = np.arange('2017-01-01', '2018-01-01', 2,
                                  dtype='datetime64[D]')

И это все, что вам нужно знать о DateTimes в Numpy! Феве, это было много.

Чтобы проложить его, давайте визуализируем фондовый рынок США за последнее десятилетие, используя разные временные интервалы.

Как визуализировать фондовый рынок с DateTime Numpy?

Для следующего примера я скачал последние 10 лет данных фондового рынка для S & P 500 Отказ Вы можете свободно загружать его здесь Отказ

Я проделал предварительную обработку от этой статьи и завершился двумя списками. Первый, Значения, Содержит значение индекса S & P 500 в закрытии каждый день с 2009-10-23 до 2019-10-22. Второй, datetimes содержит np.dateTime64 объекты на каждый день.

>>> values[:5]
[1079.6, 1066.95, 1063.41, 1042.63, 1066.11]
 
>>> datetimes[:-6:-1]
[numpy.datetime64('2019-10-22'),
numpy.datetime64('2019-10-21'),
numpy.datetime64('2019-10-18'),
numpy.datetime64('2019-10-17'),
numpy.datetime64('2019-10-16')]

Я зацикливаю эти списки вместе, чтобы создать словарь, где каждый ключ является датой и каждым значением значение S & P 500. Мы будем использовать это для создания подмножеств наших данных позже, только выбрав ключи, которые мы хотим.

# Dictionary comprehensions are equally as wonderful as list comprehensions
sp500 = {date: val for date, val in zip(datetimes, values)}

Участок 1 – все данные

plt.plot(datetimes, values)
plt.xlabel('Year')
plt.ylabel('SP500 Index')
plt.title('SP500 Index Every Day from 2010-2019')
plt.show()

Во всем наборе данных наблюдается огромная тенденция. Но график довольно шумный. Можно увидеть другие тенденции, но потому что есть так много очков, это не особенно приятно смотреть. Что делать, если мы повторно выбирали, чтобы увидеть, как рынок исполнился год на год? Для этого мы посмотрим на 1 января каждый год.

Участок 2 – 1 янв

Примечание: 1 ян Ян – это праздник каждый год, и поэтому фондовый рынок не открыт. Итак, мы будем использовать np.busday_offset () Чтобы выбрать ближайшую действительную дату для нас.

Во-первых, создайте список каждый год, используя NP.Arge ().

all_years = np.arange('2010', '2020', dtype='datetime64[Y]')

Так как значения datetimes У единицы времени «D» мы должны преобразовать даты в All_years к этому тоже. По умолчанию по умолчанию каждый элемент к yyyy-01-01.

first_jan_dates = [np.datetime64(date, 'D') for date in all_years]

Наконец, мы применяем .get () Способ вернуть элементы, которые мы хотим от SP500. И мы обертываем их в np.busday_offset () Чтобы убедиться, что мы выбираем рабочий день.

first_jan_values = [sp500.get(np.busday_offset(date, 0, roll='forward'))
                    for date in third_jan_dates]

Теперь мы замышляем.

Это гораздо более гладкий сюжет, и очень легко понять, что годы имели положительный и отрицательный рост. Такова сила ретора!

Но этот граф слишком общий? Чтобы получить хорошую среднюю позицию, давайте посмотрим на стоимость S & P 500 в начале каждые квартал за последние 10 лет. Процесс практически идентичен тому, которое мы использовали выше.

Участок 3 – Каждый квартал

Во-первых, создайте список каждого квартала в виде YYYY-MM. Помните четверти 3 месяца!

every_quarter = np.arange('2010-01', '2019-10', 3, dtype='datetime64[M]')

Переосмысление наших объектов DateTime для «D» с использованием понимания списка.

quarter_start_dates = [np.datetime64(date, 'D') for date in every_quarter]

Наконец, мы применяем метод .get () для возврата элементов, которые мы хотим. И мы обертываем их в np.busday_offset (), чтобы убедиться, что мы выбираем рабочий день.

quarter_start_values = [sp500.get(np.busday_offset(date, 0, roll='forward'))
                        for date in quarter_start_dates]

Теперь мы замышляем

plt.plot(quarter_start_dates, quarter_start_values)
plt.show()

Это дает нам прекрасный обзор тенденций фондового рынка. Это не слишком шумно (как сюжет 1) или чрезмерно упрощенный (например, сюжет 2). Внутрилетние провалы ясны, пока график все еще легко понятен.

И именно это! Все, что вам нужно знать, чтобы использовать NP.DATETETIME64 и связанные с ними функции, а также некоторые реальные примеры мира.

Если у вас есть какие-либо вопросы или предложения, пожалуйста, используйте окно комментариев ниже. Мы любим услышать отзывы и предложения!

Атрибуция

Эта статья способна предоставлена пользователем Finxter Адам Мерфи (данные ученый):

Я являюсь самоучками программистом с первой степенью класса в математике из Университета Дарема и кодировал с июня 2019 года.

Я хорошо разбираюсь в основах SUB STRACKING и DATA SCAIL и может получить широкий спектр информации из Web очень быстро.

Недавно я счел информацию обо всех часах, которые Breitling и Rolex продают всего за 48 часов и уверены в себе, я могу доставить наборы данных подобного качества для вас, независимо от ваших потребностей.

Будучи собственным английским языком, мои навыки общения отлично, и я доступен, чтобы ответить на любые вопросы, которые вы имеете, и предоставим регулярные обновления о прогрессе моей работы.

Если вы хотите нанять Адама, проверьте его Профиль намного !

Куда пойти отсюда?

Тщательное понимание Numpy Basics является важной частью образования каких-либо данных ученых. Numpy находится в основе многих передовых машин обучения и научных библиотек данных, таких как Pandas, Tensorflow и Scikit-Suart.

Если вы боретесь с Numpy Library – не бойся нет! Станьте Numpy Professional в кратчайшие сроки с нашим новым учебником кодирования «Coffe Break Numpy». Это не только тщательное введение в Numpy Library, которая повысит вашу ценность на рынке. Также весело пройти большую коллекцию кода головоломки в книге.

Получить ваш перерыв на кофе Numpy!

использованная литература

[1] https://docs.scipy.org/doc/numpy/reference/arrays.dateTime.html.

[2] https://www.iso.org/iso-8601-date-andtime-format.html.

[3] https://fred.stlouisfed.org/series/sp500/ Скачать данные SP500 здесь

[4] https://en.wikipedia.org/wiki/history_of_python

[5] https://docs.cscipy.org/doc/numpy/reference/generated/numpy.busday_offset.html#numpy.busday_offset.

[6] https://us.spindices.com/indices/equity/sp-500.

Expert Writer & Content Creator – наука о науке и машине. – Я помогаю образовательным компаниям создавать привлечение в блоге и видеоконтентах преподавания данных науки для начинающих. В отличие от моих конкурентов, я узнаю новые концепции каждый день и так понимаю, что это нравится быть студентом. Мои статьи легко понять, эффективны и приятно читать. Мои видео достойны, участвуют и подробно. – Работать со мной, пожалуйста, обратитесь к Upwork https://tinyurl.com/hire-adam-murphy