pd.to_datetime не работает с старыми датами

Вопрос или проблема

У меня есть 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), указывая на то, что дата выходит за пределы поддерживаемого диапазона.

Какой есть выход?

  1. Использование индекса периодов (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
  2. Использование альтернативных библиотек:

    Если ваш проект требует частого использования старых дат, вы можете рассмотреть использование других библиотек, таких как 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, которые обеспечивают большую гибкость в работе со старыми датами. Выбор правильного подхода зависит от ваших конкретных требований к проекту.

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

Оцените материал
Добавить комментарий

Капча загружается...