Более быстрое решение для форматирования даты - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь изменить формат даты в кадре данных pandas. Если я проверю дату в начале, у меня будет:

df['Date'][0]
Out[158]: '01/02/2008'

Тогда я использую:

df['Date'] = pd.to_datetime(df['Date']).dt.date  

Чтобы изменить формат на

df['Date'][0]
Out[157]: datetime.date(2008, 1, 2)

Однако, это занимает очень много времени, так как мой фрейм данных содержит миллионы строк.

Все, что я хочу сделать, это изменить формат даты с ММ-ДД-ГГГГ на ГГГГ-ММ-ДД. Как я могу сделать это быстрее?

Ответы [ 3 ]

0 голосов
/ 18 января 2019

Сначала нужно свернуть на Date, используя метод groupby, чтобы уменьшить размерность задачи.

Затем вы анализируете даты в новом формате и объединяете результаты обратно в исходный фрейм данных.

Это требует некоторого времени из-за слияния, но оно использует тот факт, что многие даты повторяются большое количество раз. Вы хотите конвертировать каждую дату только один раз!

Вы можете использовать следующий код:

date_parser = lambda x: pd.datetime.strptime(str(x), '%m/%d/%Y')

df['date_index'] = df['Date']
dates = df.groupby(['date_index']).first()['Date'].apply(date_parser)

df = df.set_index([ 'date_index' ])
df['New Date'] = dates
df = df.reset_index()

df.head()

В моем случае время выполнения для DataFrame с 3 миллионами строк уменьшилось с 30 до примерно 1,5 секунд.

0 голосов
/ 18 января 2019

Следуя указаниям в комментарии @ pygo, я обнаружил, что моя ошибка заключалась в том, чтобы попытаться прочитать данные как

df['Date'] = pd.to_datetime(df['Date']).dt.date  

Это будет так, как этот ответ объясняет:

Это связано с тем, что pandas возвращается к dateutil.parser.parse для анализа строк, когда он имеет формат не по умолчанию или когда строка формата не указана (это гораздо более гибко, но и медленнее).

Как вы показали выше, вы можете улучшить производительность, предоставив строку формата to_datetime.Или другой вариант - использовать infer_datetime_format = True

При использовании любого из анализаторов даты из приведенных выше ответов мы переходим к циклу for.Кроме того, когда мы указываем желаемый формат (вместо того, который у нас есть) в pd.to_datetime, мы также переходим в цикл for.

Следовательно, вместо того, чтобы делать

df['Date'] = pd.to_datetime(df['Date'],format='%Y-%m-%d')

или

df['Date'] = pd.to_datetime(df['Date']).dt.date  

, мы должны сделать

df['Date'] = pd.to_datetime(df['Date'],format='%m/%d/%Y').dt.date

, предоставив текущий формат данных, это очень быстро читается в формате datetime.Затем, используя .dt.date, быстро изменить его на новый формат без анализатора.

Спасибо всем, кто помог!

0 голосов
/ 18 января 2019

Я не уверен, поможет ли это с проблемой производительности, поскольку я не проверял набор данных вашего размера, но, по крайней мере, теоретически, это должно помочь.Pandas имеет встроенный параметр, который вы можете использовать, чтобы указать, что он должен загружать столбец как поле даты или даты и времени.См. Параметр parse_dates в документации по пандам.

Просто передайте список столбцов, которые вы хотите проанализировать как дату, и pandas преобразует столбцы для вас при создании DataFrame.Тогда вам не придется беспокоиться о циклическом возврате через фрейм данных и попытке преобразования после.

import pandas as pd

df = pd.read_csv('test.csv', parse_dates=[0,2])

В приведенном выше примере будет попытаться проанализировать 1-й и 3-й (начиная с нуля) столбцы как даты.

Тип каждого результирующего значения столбца будет меткой времени панд, и вы можете использовать панд для распечатки этого, как вам будет удобно при работе с фреймом данных.

...