Как автоматически определять столбцы даты / даты и времени и устанавливать их тип данных при чтении файла CSV в Pandas

Исходный узел: 1106147

Как автоматически определять столбцы даты / даты и времени и устанавливать их тип данных при чтении файла CSV в Pandas

Когда 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(), а затем автоматически обнаружила и преобразовала тип данных двух обнаруженных столбцов datetime. (Содержимое этого df будет показано ниже.)

Если бы я использовал обычный Pandas pd.read_csv(), я бы получил просто общие типы данных объекта по умолчанию, как показано ниже (красные прямоугольники):

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



Обратите внимание, что единственное отличие от исходного кода заключается в операторе импорта, где я изменил «из dt_auto» на «из панд». Этого достаточно, если вы везде используете только «=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 и преобразовано в дату и время. Другими словами, мы не позволим ему когда-либо преобразовать строку в pd.NaT («неудачный» результат), потому что он не может понять его как дату и время.
  2. Он будет не попытаться преобразовать столбцы, которые уже были интерпретированы как имеющие любой тип, отличный от объекта, т. е. любой конкретный тип, такой как 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 (которые обычно имеют букву «T», отделяющую дату от времени, а не от пробела). Я не экспериментировал с датами, которые включают информацию о часовом поясе, потому что я обычно не вижу таких данных, но, пожалуйста, дайте мне знать в ответном комментарии, можно ли их лучше обрабатывать путем дальнейших изменений в коде.

Что вы думаете? Считаете ли вы эту небольшую статью полезной? И должен ли сам Pandas добавить (например, к самой функции pd.read_csv?) возможность опционально сделать это для нас, чтобы вам не нужно было копировать/импортировать мой код dt_auto.py выше? Я был бы рад видеть ваши комментарии и вопросы в качестве ответов здесь.

 
Спасибо Эллиоту Ганну.

 
Bio: Дэвид Б. Розен (доктор философии) является ведущим специалистом по данным в области автоматического одобрения кредитов в 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.

Отметка времени:

Больше от КДнаггетс