Коротко
pd.to_datetime(s)превращает строки в типdatetime64. Свой формат —format="%d.%m.%Y", дата вида 01.03 —dayfirst=True, нераспознанные значения вNaT—errors="coerce".- Через
.dtдоступны части даты:.dt.year,.dt.month,.dt.day_name(),.dt.hour,.dt.date. - Разность дат — промежуток (
Timedelta):.dt.days,.dt.total_seconds(). .dt.floor("D")округляет вниз до дня, часа и т. д.;.dt.strftime(...)форматирует в строку.- «Плюс месяц» с учётом календаря —
pd.DateOffset(months=1). - В pandas 3 даты из строк хранятся с точностью до микросекунд (раньше — наносекунд).
Синтаксис
pd.to_datetime(s, format=None, dayfirst=False, errors="raise")
s.dt.year, s.dt.month, s.dt.day, s.dt.hour, s.dt.date
s.dt.day_name(), s.dt.floor("h"), s.dt.strftime("%d.%m.%Y")
(end - start).dt.days, (end - start).dt.total_seconds()
s + pd.DateOffset(months=1), s + pd.Timedelta(days=3)Параметры
ПараметрЧто делаетПо умолчанию
formatформат строки: "%d.%m.%Y %H:%M", "ISO8601" или "mixed"определяется по первому значениюdayfirstв неоднозначных датах сначала день: 01.03 — 1 мартаFalseerrors"raise" — ошибка, "coerce" — NaT для нераспознанных"raise"unitдля чисел: единица — "s", "ms", "us", "ns"NoneПримеры
orders = pd.DataFrame({
"created": ["2024-03-01 09:15", "2024-03-02 18:40", "2024-03-09 11:05"],
"shipped": ["2024-03-03 10:00", "2024-03-02 21:10", "2024-03-12 16:30"],
})created = pd.to_datetime(orders["created"])
createdВывод
0 2024-03-01 09:15:00 1 2024-03-02 18:40:00 2 2024-03-09 11:05:00 Name: created, dtype: datetime64[us]
print(pd.to_datetime(["01.03.2024", "15.04.2024"], format="%d.%m.%Y"))
pd.to_datetime(["01.03.2024"], dayfirst=True)Вывод
DatetimeIndex(['2024-03-01', '2024-04-15'], dtype='datetime64[us]', freq=None) DatetimeIndex(['2024-03-01'], dtype='datetime64[us]', freq=None)
pd.to_datetime(pd.Series(["2024-03-01", "не указано"]), errors="coerce")Вывод
0 2024-03-01 1 NaT dtype: datetime64[us]
created = pd.to_datetime(orders["created"])
pd.DataFrame({
"date": created.dt.date,
"month": created.dt.month,
"weekday": created.dt.day_name(),
"hour": created.dt.hour,
})Вывод
date month weekday hour 0 2024-03-01 3 Friday 9 1 2024-03-02 3 Saturday 18 2 2024-03-09 3 Saturday 11
created = pd.to_datetime(orders["created"])
shipped = pd.to_datetime(orders["shipped"])
delay = shipped - created
print(delay)
delay.dt.total_seconds() / 3600 # в часахВывод
0 2 days 00:45:00 1 0 days 02:30:00 2 3 days 05:25:00 dtype: timedelta64[us] 0 48.750000 1 2.500000 2 77.416667 dtype: float64
created = pd.to_datetime(orders["created"])
print(created.dt.floor("D").tolist()) # до начала дня
created.dt.strftime("%d.%m.%Y")Вывод
[Timestamp('2024-03-01 00:00:00'), Timestamp('2024-03-02 00:00:00'), Timestamp('2024-03-09 00:00:00')]
0 01.03.2024
1 02.03.2024
2 09.03.2024
Name: created, dtype: strcreated = pd.to_datetime(orders["created"])
created + pd.DateOffset(months=1) # плюс календарный месяцВывод
0 2024-04-01 09:15:00 1 2024-04-02 18:40:00 2 2024-04-09 11:05:00 Name: created, dtype: datetime64[us]
Подводные камни
Разные форматы в одном столбце
Формат определяется по первой строке и применяется ко всем. Если форматы различаются, передайте format="ISO8601" (все ISO, но разной точности) или format="mixed".
pd.to_datetime(pd.Series(["2024-03-01 10:00", "2024-03-05"])) # формат определяется по первой строкеОшибка
ValueError: time data "2024-03-05" doesn't match format "%Y-%m-%d %H:%M". You might want to try:
- passing `format` if your strings have a consistent format;
- passing `format='ISO8601'` if your strings are all ISO8601 but not necessarily in exactly the same format;
- passing `format='mixed'`, and the format will be inferred for each element individually. You might want to use `dayfirst` alongside this.pd.to_datetime(pd.Series(["2024-03-01 10:00", "2024-03-05"]), format="ISO8601")Вывод
0 2024-03-01 10:00:00 1 2024-03-05 00:00:00 dtype: datetime64[us]
Микросекунды вместо наносекунд
created = pd.to_datetime(orders["created"])
print(created.dtype) # pandas 3: микросекунды
created.astype("int64").iloc[0] # число в микросекундах, а не наносекундахВывод
datetime64[us] np.int64(1709284500000000)