Як автоматично визначити стовпці дати/дати та встановити їх тип даних під час читання файлу CSV у Pandas

Вихідний вузол: 1106147

Як автоматично визначити стовпці дати/дати та встановити їх тип даних під час читання файлу CSV у Pandas

Ключові слова: Обробка даних, Панди, Python

Коли read_csv( ) зчитує, наприклад, «2021-03-04» і «2021-03-04 21:37:01.123» як просто «об’єктні» типи даних, часто ви можете просто автоматично перетворити їх усі відразу на справжні типи даних дати і часу.


By Девід Б. Розен (доктор філософії), провідний спеціаліст із автоматизованого затвердження кредитів у IBM Global Financing



Скажімо, у мене є файл даних CSV, який я хочу прочитати у фреймі даних Pandas, і деякі його стовпці є датами або датами і часом, але я не хочу завдавати собі клопоту з визначенням/вказуванням назв цих стовпців заздалегідь. Натомість я хотів би автоматично отримати типи даних, показані в df.info() вихід на фото вище, де були відповідні стовпці автоматично заданий тип даних datetime (зелені рамки). Ось як це зробити:

from dt_auto import read_csv
df=read_csv('myfile.csv')

Зауважте, що я зробив НЕ безпосередньо викличте pd.read_csv (версія read_csv для Pandas). Моя функція dt_auto.read_csv (див. її код нижче) сама викликала pd.read_csv(), а потім автоматично виявила та перетворила тип даних двох виявлених стовпців дати і часу. (Вміст цього df буде показано нижче.)

Якби я використовував звичайний Pandas pd.read_csv(), я б отримав лише загальні типи даних об’єктів за замовчуванням, як показано нижче (червоні рамки):

from pandas import read_csv
df=read_csv('myfile.csv')
df.info()



Зауважте, що єдина відмінність від оригінального коду полягає в операторі імпорту, де я змінив «з dt_auto» на «з pandas». Цього достатньо, якщо ви використовуєте лише «=read_csv()» у всьому, не кваліфікуючи його як «=pd.read_csv()» або «=dt_auto.read_csv()».

Ось вміст мого dt_auto.py («автоматична дата і час»):

import pandas as pd
def dt_inplace(df): """Automatically detect and convert (in place!) each dataframe column of datatype 'object' to a datetime just when ALL of its non-NaN values can be successfully parsed by pd.to_datetime(). Also returns a ref. to df for convenient use in an expression. """ from pandas.errors import ParserError for c in df.columns[df.dtypes=='object']: #don't cnvt num try: df[c]=pd.to_datetime(df[c]) except (ParserError,ValueError): #Can't cnvrt some pass # ...so leave whole column as-is unconverted return df
def read_csv(*args, **kwargs): """Drop-in replacement for Pandas pd.read_csv. It invokes pd.read_csv() (passing its arguments) and then auto- matically detects and converts each column whose datatype is 'object' to a datetime just when ALL of the column's non-NaN values can be successfully parsed by pd.to_datetime(), and returns the resulting dataframe. """ return dt_inplace(pd.read_csv(*args, **kwargs))

Але хіба це не ризиковано? Що робити, якщо один із стовпців не був повністю стовпцем дати й часу? Звичайно, у вас можуть бути деякі незрозумілі рядки, які просто виглядають як дати, але не є, але немає великого ризику, що цей код сліпо перетворить або втратить рядки, які не мають дати і часу, з двох причин:

  1. Цей код буде НЕ перетворити будь-які значення в стовпці, якщо кожен Не-NaN значення в цьому стовпці можна успішно проаналізувати за допомогою pd.to_datetime та перетворити на datetime. Іншими словами, ми не дозволимо йому коли-небудь перетворювати рядок у pd.NaT (результат «збою»), тому що він не може зрозуміти його як дату і час.
  2. Це буде НЕ спробуйте перетворити стовпці, які вже були інтерпретовані як будь-який тип, відмінний від object, тобто будь-який конкретний тип, як-от int64 або float64, навіть якщо pd.to_datetime щасливо (але, ймовірно, небажано) перетворив би число, наприклад 2000, у дату 2000-01 -01.

З мого досвіду, функція dt_auto.read_csv не вимагає багато часу для виконання на типовому фреймі даних. Навіть якщо є багато стовпців об’єкта (рядка) без дати-часу, він майже завжди дуже швидко зустрічає значення у верхній частині кожного такого стовпця, яке не може розібрати як дату-час, і відмовляється та переходить до наступного стовпця. не намагаючись проаналізувати інші значення стовпця.

Ось як виглядає результуючий фрейм даних із dt_auto.read_csv(), хоча, дивлячись на нього, не обов’язково можна сказати, що два відповідні стовпці дійсно є типами даних дати і часу. Як це трапилося, файл CSV мав різну кількість десяткових знаків (три, жодного та дев’ять) для секунд у Update_Timestamp, але сам тип даних datetime показує дев’ять таких цифр незалежно від того. Дата народження у файлі csv насправді мала лише дати (без часу), але зберігалася як повна дата і час з нулями для годин, хвилин і секунд (включаючи нуль як десяткову частину), але всі компоненти часу в стовпці значення нуля змушує Pandas відображати лише дату (рік-місяць-день) для цього стовпця.



Звичайно, pd.to_datetime, і, таким чином, dt_auto.read_csv, не можуть обробляти всі можливі формати дати та дати і часу за замовчуванням, але він оброблятиме багато поширених однозначних (зазвичай рік, місяць день) форматів, таких як ті, які записуються методом dataframe.to_csv та багато інших інструменти, включаючи багато форматів дати і часу ISO (які зазвичай мають «Т», що відокремлює дату від часу, а не пробіл). Я не експериментував із датами і часом, які включають інформацію про часовий пояс, тому що я зазвичай не бачу таких даних, але будь ласка, повідомте мені у коментарі відповіді, чи можна це краще обробити шляхом подальших змін у коді.

Що ти думаєш? Вам була корисна ця невелика стаття? І чи повинна Pandas сама додавати (наприклад, до самої функції pd.read_csv?) можливість робити це за нас, щоб вам не потрібно було копіювати/імпортувати мій код dt_auto.py вище? Буду радий побачити тут ваші коментарі та запитання як відповіді.

 
Дякую Еліоту Ганну.

 
Біо: Девід Б. Розен (доктор філософії) є провідним спеціалістом із автоматизованого затвердження кредитів у IBM Global Financing. Більше з написаного Девіда див dabruro.medium.com.

Оригінал. Повідомлено з дозволу.

За темою:

Джерело: https://www.kdnuggets.com/2021/10/auto-detect-date-datetime-columns-and-set-their-datatype-when-reading-a-csv-file-in-pandas.html

Часова мітка:

Більше від KDnuggets