#python #pandas
Вопрос:
Я работаю с фреймом данных, содержащим дату в строковом формате. Даты выглядят так: 19620201, так что сначала год, затем месяц, затем день.
Я хочу преобразовать эти даты в дату и время. Я пытался использовать это: pd.to_datetime(df.Date)
Но это не работает, потому что у какой-то даты есть день до «00», иногда это месяц, а иногда даже год.
Я не хочу отказываться от этих дат, потому что у меня все еще есть годы или месяцы.
Поэтому я попытался написать функцию, подобную этой:
def handle_the_00_case(date):
try:
if date.endswith("0000"):
return pd.to_datetime(date[:-4], format="%Y")
elif date.endswith("00"):
return pd.to_datetime(date[:-2], format="%Y%m")
return pd.to_datetime(date, format="%Y%m%d")
except ValueError:
return
И используйте следующее утверждение:
df.Date.apply(handle_the_00_case)
Но это действительно слишком долго для вычислений.
У вас есть идеи о том, как я могу улучшить скорость этого ? Я попробовал библиотеку np.vectorize()
и более быструю библиотеку, но это не работает, я знаю, что должен изменить способ написания функции, но я не знаю как.
Спасибо, если вы можете мне помочь ! 🙂
Ответ №1:
Сначала вы должны преобразовать столбец в действительные даты, а затем преобразовать в дату и время только один раз:
date = df['Date'].str.replace('0000
Комментарии:
1. Да, спасибо тебе ! Я только что попробовал, на данный момент это самый быстрый метод, который я пробовал. Это действительно здорово работает ! Большое вам спасибо :)
2. @ClementHuriaux - Что такое время в ваших данных? Это быстрее, как
np.where
?3. @jezrael Да, это так, если я возьму время инициализации (я имею в виду назначение d1, d2 и т.д.). np.where намного быстрее вычисляется (4,9 мс), но общее время составляет 2,8 с, когда я использовал все время. Решение Даниэля требует больше времени для вычислений, но в конце общее время составляет 1,6 с, так что это немного быстрее
Ответ №2:
Первая идея состоит в том, чтобы использовать векторизованное решение с пропуском столбца в to_datetime
и генерированием выходного столбца с помощью numpy.where
:
d1 = pd.to_datetime(df['Date'].str[:-4], format="%Y", errors='coerce')
d2 = pd.to_datetime(df['Date'].str[:-2], format="%Y%m", errors='coerce')
d3 = pd.to_datetime(df['Date'], format="%Y%m%d", errors='coerce')
m1 = df['Date'].str.endswith("0000")
m2 = df['Date'].str.endswith("00")
df['Date_out'] = np.where(m1, d1, np.where(m2, d2, d3))
Комментарии:
1. Большое вам спасибо, это так хорошо работает. Только что попробовал свои 650000 строк. С применением потребовалось 67 секунд. С np.где это заняло 4,9 мс. Я собираюсь прочитать документы о np.куда идти дальше. Еще раз большое вам спасибо ! 🙂
,'0101')
date = date.str.replace('00
Комментарии:
1. Да, спасибо тебе ! Я только что попробовал, на данный момент это самый быстрый метод, который я пробовал. Это действительно здорово работает ! Большое вам спасибо 🙂
2. @ClementHuriaux - Что такое время в ваших данных? Это быстрее, как
np.where
?3. @jezrael Да, это так, если я возьму время инициализации (я имею в виду назначение d1, d2 и т.д.). np.where намного быстрее вычисляется (4,9 мс), но общее время составляет 2,8 с, когда я использовал все время. Решение Даниэля требует больше времени для вычислений, но в конце общее время составляет 1,6 с, так что это немного быстрее
Ответ №2:
Первая идея состоит в том, чтобы использовать векторизованное решение с пропуском столбца в to_datetime
и генерированием выходного столбца с помощью numpy.where
:
Комментарии:
1. Большое вам спасибо, это так хорошо работает. Только что попробовал свои 650000 строк. С применением потребовалось 67 секунд. С np.где это заняло 4,9 мс. Я собираюсь прочитать документы о np.куда идти дальше. Еще раз большое вам спасибо ! 🙂
,'01')
date = pd.to_datetime(date, format="%Y%m%d")
Комментарии:
1. Да, спасибо тебе ! Я только что попробовал, на данный момент это самый быстрый метод, который я пробовал. Это действительно здорово работает ! Большое вам спасибо 🙂
2. @ClementHuriaux — Что такое время в ваших данных? Это быстрее, как
np.where
?3. @jezrael Да, это так, если я возьму время инициализации (я имею в виду назначение d1, d2 и т.д.). np.where намного быстрее вычисляется (4,9 мс), но общее время составляет 2,8 с, когда я использовал все время. Решение Даниэля требует больше времени для вычислений, но в конце общее время составляет 1,6 с, так что это немного быстрее
Ответ №2:
Первая идея состоит в том, чтобы использовать векторизованное решение с пропуском столбца в to_datetime
и генерированием выходного столбца с помощью numpy.where
:
Комментарии:
1. Большое вам спасибо, это так хорошо работает. Только что попробовал свои 650000 строк. С применением потребовалось 67 секунд. С np.где это заняло 4,9 мс. Я собираюсь прочитать документы о np.куда идти дальше. Еще раз большое вам спасибо ! 🙂