Вопрос или проблема
У меня есть csv файл с очень старыми датами, и pd.to_datetime не работает. В polars это работает. Является ли это врожденным ограничением в pandas, ошибкой или чем-то еще?
import pandas as pd
dates = ["12/31/1672","12/31/1677","10/19/2024"]
df = pd.DataFrame(dates, columns=['Date'])
df['Date'] = pd.to_datetime(df['Date'], format="%m/%d/%Y", errors="coerce")
df
Date
0 NaT
1 1677-12-31
2 2024-10-19
в polars
import polars as pl
df = pl.DataFrame({ 'Date': dates})
df = df.with_columns(pl.col('Date').str.strptime(pl.Date, format="%m/%d/%Y"))
df
shape: (3, 1)
┌────────────┐
│ Date │
│ --- │
│ date │
╞════════════╡
│ 1672-12-31 │
│ 1677-12-31 │
│ 2024-10-19 │
└────────────┘
pandas имеет ограничения по временным меткам; документация предлагает использовать period
для таких случаев (конечно, это зависит от того, охватывает ли тип данных period
ваш случай использования):
df.assign(new_dates=pd.PeriodIndex(df.Date, freq='D'))
Date new_dates
0 12/31/1672 1672-12-31
1 12/31/1677 1677-12-31
2 10/19/2024 2024-10-19
Ответ или решение
Проблема с преобразованием старых дат в Pandas: Возможные решения и альтернативы
При работе с данными, содержащими очень старые даты, многие пользователи сталкиваются с проблемами при использовании метода pd.to_datetime()
в библиотеке Pandas. Это связано с ограничениями, установленными в самой библиотеке, и важно понимать как природу этих ограничений, так и возможные альтернативные способы обработки таких данных.
Почему pd.to_datetime()
не работает с очень старыми датами?
Как указано в документации Pandas, существует ограничение на диапазон временных меток, которые можно использовать. По умолчанию Pandas реализует временные метки, которые охватывают интервал с 1677 года до 2262 года. Это связано с тем, что Pandas основан на библиотеке NumPy, где datetime64
имеет фиксированный диапазон.
Когда вы пытаетесь конвертировать дату, например, "12/31/1672", с помощью pd.to_datetime()
, метод возвращает NaT
(Not a Time), указывая на то, что дата выходит за пределы поддерживаемого диапазона.
Какой есть выход?
-
Использование индекса периодов (PeriodIndex):
В случаях, когда диапазон временных меток Pandas не соответствует требованиям, вы можете использовать
pd.PeriodIndex
. Например, следующий код успешно конвертирует старые даты в индекс периодов:import pandas as pd dates = ["12/31/1672", "12/31/1677", "10/19/2024"] df = pd.DataFrame(dates, columns=['Date']) df['Date'] = pd.PeriodIndex(pd.to_datetime(df['Date'], format="%m/%d/%Y", errors="coerce"), freq='D') print(df)
В результате вы получите следующий DataFrame:
Date 0 1672-12-31 1 1677-12-31 2 2024-10-19
-
Использование альтернативных библиотек:
Если ваш проект требует частого использования старых дат, вы можете рассмотреть использование других библиотек, таких как Polars, которые не имеют тех же ограничений на время. Например:
import polars as pl df = pl.DataFrame({'Date': dates}) df = df.with_columns(pl.col('Date').str.strptime(pl.Date, format="%m/%d/%Y")) print(df)
Это позволит вам работать с датами, выходящими за пределы стандартных временных меток Pandas.
Заключение
Проблема, с которой вы столкнулись, связана с моделью представления времени в Pandas и её ограничениями. Однако есть рабочие решения, такие как использование PeriodIndex
или переход на альтернативные библиотеки, такие как Polars, которые обеспечивают большую гибкость в работе со старыми датами. Выбор правильного подхода зависит от ваших конкретных требований к проекту.
Это важное решение, которое может существенно улучшить обработку временных данных в ваших проектах, особенно если вы работаете с историческими записями или архивами.