Сообщить об ошибке.

Функция to_datetime() модуля pandas в Python

Преобразование данных, похожих на дату/время в представление "datetime"

Синтаксис:

pandas.to_datetime(arg, errors='raise', dayfirst=False, yearfirst=False, 
                   utc=False, format=None, exact=no_default, 
                   unit=None, infer_datetime_format=no_default, 
                   origin='unix', cache=True)

Параметры:

  • arg - объект, преобразуемый в datetime. Принимает int, float, str, datetime, list, tuple, 1-d array, Series, DataFrame или словароподобный объект.

  • errors='raise' - принимает ‘ignore’, ‘raise’, ‘coerce’

    • Если 'raise', то недопустимый синтаксический анализ вызовет исключение.
    • Если 'coerce', то при неверном синтаксическом анализе будет установлен NaT (не время).
    • Если 'ignore', то при неверном синтаксическом анализе возвращаются входные данные.

  • dayfirst=False - указывает порядок синтаксического анализа даты, если arg имеет значение str или похож на список. Если True, то даты анализируются в европейском стиле (т.е. строка с датой начинается с указания дня). То есть строка даты '10/11/24' будет анализироваться как 2024-11-10.

    Предупреждение: аргумент dayfirst=True не является строгим. Другими словами, если дата не может быть проанализирована таким образом, то она будет проанализирована так, как если бы dayfirst=False.

  • yearfirst=False - указывает порядок синтаксического анализа даты, если arg имеет значение str или похож на список.

    • Если True, то анализирует даты так, как если бы строка с датой начиналась с указания года. То есть строка даты '24/11/12' анализируется как 2024-11-12.
    • Если оба аргумента dayfirst и yearfirst имеют значение True, то предпочтение отдается yearfirst.

    Предупреждение. Аргумент yearfirst=True не является строгим. Другими словами, если дата не может быть проанализирована таким образом, то она будет проанализирована так, как если бы yearfirst=False.

  • utc=False - контролирует синтаксический анализ, локализацию и преобразование часовых поясов.

    • если True, то функция всегда возвращает pandas.Timestamp, pandas.Series или pandas.DatetimeIndex, локализованные в формате UTC с учетом часового пояса. Входные данные не зависящие от часовых поясов локализуются в формате UTC, а входные данные, учитывающие часовой пояс, преобразуются в UTC.
    • если False (по умолчанию), входные данные не будут приводиться к UTC. Входные данные, не зависящие от часового пояса, останутся "наивными", в то время как входные данные, учитывающие часовой пояс, сохранят свои временные смещения. Существуют ограничения для смешанных смещений (как правило, в не должно присутствовать переход на летнее время).

    Предупреждение. В будущей версии pandas (>2.1) синтаксический анализ даты и времени со смешанными часовыми поясами вызовет ошибку. Укажите utc=True, чтобы согласиться на новое поведение и отключить это предупреждение. Чтобы создать Series со смещениями и типом dtype: object, нужно использовать метод .apply() и datetime.datetime.strptime().

  • format=None - строка (лекало) для разбора даты/времени, например '%d/%m/%Y'. Правила форматирования такие-же как у методов .strftime() и .strptime() модуля datetime. Обратите внимание, что '%f' будет анализировать вплоть до наносекунд.

    Также можно использовать строки:

    • 'ISO8601', для разбора любой ISO8601 временной строки (не обязательно в точно таком же формате);
    • 'mixed', чтобы определить формат для каждого элемента в отдельности. Это рискованно, и вероятно, его следует использовать совместно с аргументом dayfirst.

    Заметка. Если передан DataFrame, то аргумент format не действует.

  • exact=no_default - управление использованием формата:

    • если True, требуется точное совпадение формата.
    • если False, формат должен совпадать в любом месте целевой строки.
    • Нельзя использовать вместе с format='ISO8601' или format='mixed'.

  • unit=None - единица измерения аргумента arg (принимает 'D', 's', 'ms', 'us', 'ns') обозначает единицу, которая является целым числом или числом float (по другому точность). Например, с unit='ms' и origin='unix' вычисляется количество миллисекунд до начала эпохи unix.

  • infer_datetime_format=no_default - если True и не указан формат format, то будет пытаться выяснить формат даты и времени на основе первого элемента, отличного от NaN, и, если это возможно, переключится на более быстрый метод их синтаксического анализа. В некоторых случаях это может увеличить скорость парсинга в 5-10 раз. (Устарело, с версии 2.0.0: теперь по умолчанию используется строгая версия этого аргумента, его передача не имеет никакого эффекта)

  • origin='unix' - определяет контрольную дату. Числовые значения будут проанализированы как количество единиц (определяемых единицами измерения) с этой контрольной даты.

    • Если 'unix' (или POSIX). Начальная дата устанавливается на 1970-01-01.
    • Если 'julian', единица измерения должна быть 'D', а начальная дата устанавливается на начало юлианского календаря. Юлианский день под номером 0 присваивается дню, начинающемуся в полдень 1 января 4713 года до нашей эры.
    • Если передается pandas.Timestamp (pandas.Timestamp, dt.datetime, np.datetimt64 или строка с датой), для origin устанавливается значение pandas.Timestamp, идентифицируемое по источнику.
    • Если число float или целое число, то начальная дата - это разность миллисекунд относительно 1970-01-01.

  • cache=True - если True, то используйте кэш уникальных преобразованных дат. Может привести к значительному ускорению при синтаксическом анализе повторяющихся строк даты, особенно со смещениями часовых поясов. Кэш используется только при наличии не менее 50 значений. Наличие значений, выходящих за границы pandas.Timestamp.min или pandas.Timestamp.max, сделает кэш непригодным для использования и может замедлить синтаксический анализ.

Возвращаемое значение:

Если разбор/парсинг даты и времени удался, то тип возвращаемого значения зависит от входных данных (типы в скобках соответствуют резервному варианту в случае неудачного разбора часового пояса или выхода метки времени за пределы диапазона pd.Timestamp.min и pd.Timestamp.max):

Описание:

Функция to_datetime() модуля pandas преобразует массив/список/кортеж скалярных значений, Series или DataFrame/словароподобный объект в объект datetime библиотеки pandas (pandas.Timestamp, pandas.DatetimeIndex или Series с dtype: datetime64).

Поддерживается множество типов входных данных, которые приводят к различным типам выходных данных:

  • Скаляр может быть int, float, str, объектом datetime (или numpy.datetime64()). Он преобразуется в pandas.Timestamp, когда это возможно, в противном случае он преобразуется в datetime.datetime. Скаляры None/NaN/null преобразуются в NaT.
  • Массив/список/кортеж может содержать объекты int, float, str, datetime. Они преобразуются в pandas.DatetimeIndex, когда это возможно, в противном случае они преобразуются в Index с dtype: object, содержащим datetime.datetime. Записи None/NaN/null преобразуются в NaT.
  • Series преобразуются в Series с dtype равный datetime64 , когда это возможно, в противном случае они преобразуются в Series с dtype: object, содержащим datetime.datetime. Записи None/NaN/null преобразуются в NaT.
  • DataFrame преобразуются в Series с dtype: datetime64. Для каждой строки создается дата и время путем сборки различных столбцов DataFrame. Метки столбцов/ключи должны быть распространенными аббревиатурами, такими как ‘year’, ‘month’, ‘day’, ‘minute’, ‘second’, ‘ms’, ‘us’, ‘ns’.

Причины, приводящие к тому, что возвращаются объекты datetime.datetime (внутри Index или Series с dtype: object) вместо правильного присвоенного типа pandas (pandas.Timestamp, pandas.DatetimeIndex или Series с dtype: datetime64):

  • если какой-либо элемент входных данных находится перед pandas.Timestamp.min или после pandas.Timestamp.max.

    >>> pd.Timestamp.min
    # Timestamp('1677-09-21 00:12:43.145224193')
    >>> pd.Timestamp.max
    # Timestamp('2262-04-11 23:47:16.854775807')
    
  • когда utc=False (по умолчанию) и входные данные представляют собой массив или Series, содержащие смешанные "наивные"/"осведомленные" datetime, или "осведомленные" datetime со смешанными временными смещениями. Обратите внимание, что это происходит очень часто, когда в часовом поясе действует политика перехода на летнее время. В этом случае необходимо использовать utc=True.

Использование аргументов функции pandas.to_datetime()

Если нужно преобразовать какой-то столбец DataFrame со строками даты/времени, в представление datetime библиотеки pandas, то нужно использовать следующий код, при этом изменить название столбца 'my_col' и строку формата (аргумент format) согласно своим данным:

# допустим есть абстрактный `DataFrame` (df), где в столбце 'my_col' 
# хранятся строки с датами в формате '2024-01-01 00:00'.
# Необходимо перезаписать этот столбец преобразованными данными:
df['my_col'] = pd.to_datetime(df['my_col'], format='%Y-%m-%d %H:%M)

Чтобы преобразовать объект Series или список из объектов, похожих на дату, например: строки, числа эпохи Unix или ИХ СМЕСЬ, можно использовать функцию pandas.to_datetime(). При передаче Series возвращается Series (с тем же индексом), а список преобразуется в DatetimeIndex:

>>> pd.to_datetime(pd.Series(["Jul 31, 2023", "Jan 10, 2024", None]))
# 0   2023-07-31
# 1   2024-01-10
# 2          NaT
# dtype: datetime64[ns]

>>> pd.to_datetime(["2023/11/23", "2010/12/31"])
# DatetimeIndex(['2023-11-23', '2010-12-31'], dtype='datetime64[ns]', freq=None)

Если используются даты, которые начинаются с дня (т. е. в европейском стиле), то можно передать флаг dayfirst:

>>> pd.to_datetime(["04-01-2024 10:00"], dayfirst=True)
# DatetimeIndex(['2024-01-04 10:00:00'], dtype='datetime64[ns]', freq=None)
>>> pd.to_datetime(["04-14-2024 10:00"], dayfirst=True)
# DatetimeIndex(['2024-04-14 10:00:00'], dtype='datetime64[ns]', freq=None)

Предупреждение. В приведенном выше примере видим, что аргумент dayfirst не является строгим. Если дата не может быть проанализирована таким образом, то она будет проанализирована так, как если бы значение dayfirst было ложным, и также будет выдано предупреждение:

"UserWarning: Parsing dates in %m-%d-%Y %H:%M format when dayfirst=True was specified. Pass dayfirst=False or specify a format to silence this warning.".

Если передать одну строку в функцию pandas.to_datetime(), то она возвращает одну временную метку. Класс pandas.Timestamp также может принимать строки, но он не принимает аргумент синтаксического анализа строк, такие как dayfirst или format , поэтому для преобразования строк в объекты datetime необходимо использовать pandas.to_datetime().

>>> pd.to_datetime("2023/11/12")
# Timestamp('2023-11-12 00:00:00')
>>> pd.Timestamp("2023/11/12")
# Timestamp('2023-11-12 00:00:00')

Можно также напрямую использовать конструктор pandas.DatetimeIndex():

>>> pd.DatetimeIndex(["2024-01-01", "2024-01-03", "2024-01-05"])
# DatetimeIndex(['2024-01-01', '2024-01-03', '2024-01-05'], dtype='datetime64[ns]', freq=None)

Аргументу freq конструктора DatetimeIndex может быть передана cтрока 'infer' для того, чтобы при создании индекса установить предполагаемый период:

>>> pd.DatetimeIndex(["2024-01-01", "2024-01-03", "2024-01-05"], freq="infer")
# DatetimeIndex(['2024-01-01', '2024-01-03', '2024-01-05'], dtype='datetime64[ns]', freq='2D')

Использование аргумента format

В дополнение к строке c датой может быть передан аргумент format для обеспечения конкретного синтаксического анализа. Это также может значительно ускорить преобразование.

>>> pd.to_datetime("2023/11/12", format="%Y/%m/%d")
# Timestamp('2023-11-12 00:00:00')
>>> pd.to_datetime("12-11-2023 00:00", format="%d-%m-%Y %H:%M")
# Timestamp('2023-11-12 00:00:00')

Для получения дополнительной информации о вариантах, доступных при указании аргумента format, смотрим правила форматирования метода .strptime() встроенного модуля datetime.

Сборка даты и времени из нескольких столбцов DataFrame

Также можно передать DataFrame целочисленных или строковых столбцов для сборки в последовательность меток времени.

>>> df = pd.DataFrame(
...     {"year": [2015, 2016], "month": [2, 3], "day": [4, 5], "hour": [2, 3]}
... )
>>> df
#    year  month  day  hour
# 0  2015      2    4     2
# 1  2016      3    5     3

>>> pd.to_datetime(df)
# 0   2015-02-04 02:00:00
# 1   2016-03-05 03:00:00
# dtype: datetime64[ns]

Или отобрать только те столбцы, которые необходимо собрать.

>>> pd.to_datetime(df[["year", "month", "day"]])
# 0   2015-02-04
# 1   2016-03-05
# dtype: datetime64[ns]

Функция pd.to_datetime() ищет стандартные обозначения компонента datetime в именах столбцов, в том числе:

  • обязательные: year, month, day
  • дополнительные: hour, minute, second, millisecond, microsecond, nanosecond

Неверные данные

Поведение по умолчанию, errors='raise', заключается в том, чтобы вызвать исключение, когда дата/время не поддается анализу:

>>> pd.to_datetime(['2009/07/31', 'asd'], errors='raise')
# Traceback (most recent call last):
# ...
# ValueError: time data "asd" doesn't match format "%Y/%m/%d", at position 1.

Чтобы вернуть исходные данные, если они не поддаются анализу, нужно передать errors='ignore', :

>>> pd.to_datetime(["2009/07/31", "asd"], errors="ignore")
# Index(['2009/07/31', 'asd'], dtype='object')

Для преобразования неразобранных данных в NaT (не время), необходимо передать errors='coerce':

>>> pd.to_datetime(["2009/07/31", "asd"], errors="coerce")
# DatetimeIndex(['2009-07-31', 'NaT'], dtype='datetime64[ns]', freq=None)

Метки времени эпохи Unix

Pandas поддерживает преобразование целочисленного времени эпохи Unix или времени эпохи Unix с плавающей запятой в pandas.Timestamp и pandas.DatetimeIndex. Единицей измерения по умолчанию являются наносекунды, так как именно так хранятся объекты pandas.Timestamp. При этом значения эпохи Unix часто хранятся в другой единице, которую можно указать в аргументе unit. Они вычисляются от начальной точки, заданной аргументом origin.

>>> pd.to_datetime(
...     [1349720105, 1349806505, 1349892905, 1349979305, 1350065705], unit="s"
... )
# DatetimeIndex(['2012-10-08 18:15:05', '2012-10-09 18:15:05',
#                '2012-10-10 18:15:05', '2012-10-11 18:15:05',
#                '2012-10-12 18:15:05'],
#               dtype='datetime64[ns]', freq=None)

>>> pd.to_datetime(
...     [1349720105100, 1349720105200, 1349720105300, 1349720105400, 1349720105500],
...     unit="ms",
... )
# DatetimeIndex(['2012-10-08 18:15:05.100000', '2012-10-08 18:15:05.200000',
#                '2012-10-08 18:15:05.300000', '2012-10-08 18:15:05.400000',
#                '2012-10-08 18:15:05.500000'],
#               dtype='datetime64[ns]', freq=None)

Предупреждение. Преобразование времени эпохи с плавающей запятой может привести к неточным и неожиданным результатам. Числа float Python имеют точность около 15 цифр в десятичной дроби. Округление при преобразовании из float в метку времени высокой точности неизбежно. Единственный способ добиться точности - использовать типы фиксированной ширины (например, int64).

>>> pd.to_datetime([1490195805.433, 1490195805.433502912], unit="s")
# DatetimeIndex(['2017-03-22 15:16:45.433000088', '2017-03-22 15:16:45.433502913'], dtype='datetime64[ns]', freq=None)
>>> pd.to_datetime(1490195805433502912, unit="ns")
# Timestamp('2017-03-22 15:16:45.433502912')

Преобразование pandas.Timestamp в значение эпохи Unix

Чтобы преобразовать pandas.Timestamp в эпоху Unix необходимо вычесть из нее начало эпохи Unix и разделить на единицу времени:

>>> stamps = pd.date_range("2012-10-08 18:15:05", periods=4, freq="D")
>>> stamps
# DatetimeIndex(['2012-10-08 18:15:05', '2012-10-09 18:15:05',
#                '2012-10-10 18:15:05', '2012-10-11 18:15:05'],
#               dtype='datetime64[ns]', freq='D')

Далее вычитаем эпоху Unix (полночь 1 января 1970 года по всемирному координированному времени), а затем делим unit на "единицу" (1 секунду).

>>> (stamps - pd.Timestamp("1970-01-01")) // pd.Timedelta("1s")
# Index([1349720105, 1349806505, 1349892905, 1349979305], dtype='int64')

Использование аргумента origin

Используя аргумент origin, можно указать альтернативную отправную точку для создания pandas.DatetimeIndex. Например, чтобы использовать 1960-01-01 в качестве начальной даты:

>>> pd.to_datetime([1, 2, 3], unit="D", origin=pd.Timestamp("1960-01-01"))
# DatetimeIndex(['1960-01-02', '1960-01-03', '1960-01-04'], dtype='datetime64[ns]', freq=None)

По умолчанию установлено значение origin='unix', которое равно 1970-01-01 00:00:00. Обычно называется "начало эпохой UNIX" или временем POSIX.

>>> pd.to_datetime([1, 2, 3], unit="D")
# DatetimeIndex(['1970-01-02', '1970-01-03', '1970-01-04'], dtype='datetime64[ns]', freq=None)

Примеры использования pandas.to_datetime()

Работа с различными входными данными

Сборка даты и времени из нескольких столбцов DataFrame. Ключи могут быть распространенными аббревиатурами, такими как ‘year’, ‘month’, ‘day’, ‘minute’, ‘second’, ‘ms’, ‘us’, ‘ns’ или множественным числом того же.

>>> df = pd.DataFrame({'year': [2015, 2016],
...                    'month': [2, 3],
...                    'day': [4, 5]})
>>> pd.to_datetime(df)
# 0   2015-02-04
# 1   2016-03-05
# dtype: datetime64[ns]

Использование времени эпохи Unix:

>>> pd.to_datetime(1490195805, unit='s')
# Timestamp('2017-03-22 15:16:45')
>>> pd.to_datetime(1490195805433502912, unit='ns')
# Timestamp('2017-03-22 15:16:45.433502912')

Предупреждение. Для аргумента float может произойти округление точности. Чтобы предотвратить непредвиденное поведение, нужно использовать точный тип с фиксированной шириной.

Использование начала эпохи, отличной от Unix:

>>> pd.to_datetime([1, 2, 3], unit='D',
...                origin=pd.Timestamp('1960-01-01'))
# DatetimeIndex(['1960-01-02', '1960-01-03', '1960-01-04'],
#               dtype='datetime64[ns]', freq=None)

Различия в поведении при преобразовании строки в datetime

Разметка '%f' аргумента format будет анализировать с точностью до наносекунд.

>>> pd.to_datetime('2018-10-26 12:00:00.0000000011',
...                format='%Y-%m-%d %H:%M:%S.%f')
# Timestamp('2018-10-26 12:00:00.000000001')

Неконвертируемая дата и время

Если дата не соответствует ограничениям метки времени, передача errors='ignore' вернет исходные входные данные, а не вызовет какое-либо исключение.

Передача errors='coerce' приведет к тому, что дата, выходящая за границы, будет обозначена как NaT, в дополнение к принудительному преобразованию значений, не являющихся датами (или не поддающихся анализу дат), в NaT.

>>> pd.to_datetime('13000101', format='%Y%m%d', errors='ignore')
# '13000101'
>>> pd.to_datetime('13000101', format='%Y%m%d', errors='coerce')
# NaT

Часовые пояса и смещения времени

Поведение по умолчанию: utc=False

Входные данные, не учитывающие часовой пояс, преобразуются в DatetimeIndex, не учитывающий часовой пояс:

>>> pd.to_datetime(['2018-10-26 12:00:00', '2018-10-26 13:00:15'])
# DatetimeIndex(['2018-10-26 12:00:00', '2018-10-26 13:00:15'],
#               dtype='datetime64[ns]', freq=None)

Входные данные с учетом часового пояса и постоянным смещением времени преобразуются в DatetimeIndex с учетом часового пояса:

>>> pd.to_datetime(['2018-10-26 12:00 -0500', '2018-10-26 13:00 -0500'])
# DatetimeIndex(['2018-10-26 12:00:00-05:00', '2018-10-26 13:00:00-05:00'],
#               dtype='datetime64[ns, UTC-05:00]', freq=None)

Входные данные с учетом часового пояса со смешанными смещениями времени (например, полученные из часового пояса с переходом на летнее время, такого как Европа/Париж) не могут быть успешно преобразованы в DatetimeIndex. Анализ даты и времени со смешанными часовыми поясами выдаст предупреждение, если только utc=True. Если указать utc=False, то будет показано предупреждение ниже и будет возвращен простой Index, содержащий объекты datetime.datetime:

>>> pd.to_datetime(['2020-10-25 02:00 +0200',
...                 '2020-10-25 04:00 +0100'])  
# FutureWarning: In a future version of pandas, parsing datetimes with mixed
# time zones will raise an error unless `utc=True`. Please specify `utc=True`
# to opt in to the new behaviour and silence this warning. To create a `Series`
# with mixed offsets and `object` dtype, please use `apply` and
# `datetime.datetime.strptime`.
# Index([2020-10-25 02:00:00+02:00, 2020-10-25 04:00:00+01:00],
#       dtype='object')

Сочетание входных данных с учетом часового пояса и без учета часового пояса также преобразуется в простой Index, содержащий объекты datetime.datetime:

>>> from datetime import datetime
>>> pd.to_datetime(["2020-01-01 01:00:00-01:00",
...                 datetime(2020, 1, 1, 3, 0)])  
# FutureWarning: In a future version of pandas, parsing datetimes with mixed
# time zones will raise an error unless `utc=True`. Please specify `utc=True`
# to opt in to the new behaviour and silence this warning. To create a `Series`
# with mixed offsets and `object` dtype, please use `apply` and
# `datetime.datetime.strptime`.
# Index([2020-01-01 01:00:00-01:00, 2020-01-01 03:00:00], dtype='object')

Установка utc=True решает большинство вышеперечисленных проблем:

Входные данные, не зависящие от часового пояса, локализуются как UTC.

>>> pd.to_datetime(['2018-10-26 12:00', '2018-10-26 13:00'], utc=True)
# DatetimeIndex(['2018-10-26 12:00:00+00:00', '2018-10-26 13:00:00+00:00'],
#               dtype='datetime64[ns, UTC]', freq=None)

Входные данные с учетом часового пояса преобразуются в формат UTC (выходные данные представляют ту же дату и время, но рассматриваются со смещением времени UTC +00:00).

>>> pd.to_datetime(['2018-10-26 12:00 -0530', '2018-10-26 12:00 -0500'],
...                utc=True)
# DatetimeIndex(['2018-10-26 17:30:00+00:00', '2018-10-26 17:00:00+00:00'],
#               dtype='datetime64[ns, UTC]', freq=None)

Входные данные могут содержать как строку, так и дату и время, вышеуказанные правила по-прежнему применяются.

>>> pd.to_datetime(['2018-10-26 12:00', datetime(2020, 1, 1, 18)], utc=True)
# DatetimeIndex(['2018-10-26 12:00:00+00:00', '2020-01-01 18:00:00+00:00'],
#               dtype='datetime64[ns, UTC]', freq=None)