Как мне анализировать даты с более чем 24 часами в анализаторе dateutil в Python 3?

#python #parsing #datetime #python-3.x

#python #синтаксический анализ #дата и время #python-3.x

Вопрос:

В настоящее время у меня в столбце несколько раз написано «27:32:18», что означает, что кто-то ждал 27 часов, 32 минуты и 18 секунд. Я продолжаю получать «ValueError: час должен быть в 0 ..23» всякий раз, когда я пытаюсь проанализировать эти значения.

Как мне выполнить синтаксический анализ этих значений или преобразовать их в более стандартный формат? Я попробовал следующее в качестве теста для одного значения:

 time1 = "56:42:12"
time2 = time1.split(':')
time2 = [int(n) for n in time2]
time2.insert(0, time2[0] // 24)
time2[1] %= 24
 

На этом этапе time2 представляет собой список, состоящий из [2, 8, 42, 12], что эквивалентно 2 дням, 8 часам, 42 минутам и 12 секундам. Как бы мне преобразовать это в представление даты и времени в Python в днях, часах, минутах и секундах таким образом, чтобы Python мог его анализировать? Обратите внимание, что в конечном итоге я буду выполнять неконтролируемую кластеризацию для этих значений времени, которые представляют время ожидания.

Комментарии:

1. Это не дата . Продолжительность времени — это совсем другой зверь.

2. Объект python datetime может использоваться только для представления определенного момента времени; например, 31 июля 1889 года. Длительности выражаются в timedelta() объектах.

3. Интервал должен иметь ссылку, из которой он является дельтой. Просто сказать «2 дня, 8 часов, 42 минуты» без указания части since , затруднит определение даты . Если вы просто хотите рассчитать продолжительность времени, это (как сказал Мартинн), другое дело.

4. Спасибо! Поэтому работайте с timedeltas вместо datetimes.

Ответ №1:

У вас нет даты, у вас есть длительность. Это может быть связано с датами и временными метками, но только в том смысле, что задействованы одни и те же единицы времени и отображаются аналогично временным меткам.

Таким образом, вы не можете использовать dateutil для синтаксического анализа такие значения. Достаточно легко разделить и проанализировать самостоятельно:

 hours, minutes, seconds = map(int, time1.split(':'))
 

Затем вы можете использовать datetime.timedelta() объект для представления продолжительности:

 td = datetime.timedelta(hours=hours, minutes=minutes, seconds=seconds)
 

Затем это будет отслеживать дельту в виде дней, секунд и микросекунд:

 >>> import datetime
>>> time1 = "56:42:12"
>>> hours, minutes, seconds = map(int, time1.split(':'))
>>> datetime.timedelta(hours=hours, minutes=minutes, seconds=seconds)
datetime.timedelta(2, 31332)
 

Комментарии:

1. Спасибо! Хотя по какой-то причине это не позволяет мне фактически изменять сохраненные значения. У меня есть следующий цикл for. Пожалуйста, обратите внимание, что это код Pandas: для времени в df.elapsed_time: часы, минуты, секунды = map(int, time.split(‘:’)) time = timedelta(часы = часы, минуты = минуты, секунды = секунды)

2. Зачем вам нужно изменять сохраненные значения? Какие значения вы пытаетесь изменить?

3. Мне нужно изменить сохраненные значения, чтобы я мог анализировать данные о времени ожидания пациентов в отделении неотложной помощи. Существует другая соответствующая информация о пациенте, поэтому мне нужно, чтобы обновленные значения были в большом фрейме данных, с которым я работаю. Я пытаюсь преобразовать значения, сохраненные как «54:23:45», в временные интервалы, такие как (2, 31332), чтобы в конечном итоге я мог выполнить некоторую кластеризацию в scikit-learn.

4. Привет @BrandonSherman вы можете использовать df['elapsed_time_new'] = pd.to_timedelta(df.elapsed_time) для создания нового столбца в вашем DataFrame , который будет содержать timedelta объекты, которыми вы можете манипулировать по мере необходимости для вашего анализа. Документацию для to_timedelta можно найти здесь . Обратите внимание, что эти объекты разбиты на дни, часы, минуты, секунды, поэтому вам может потребоваться дополнительная работа, чтобы разбить его на (дни, секунды), чего вы, похоже, хотите.

5. Это действительно прискорбно: (что вы можете сделать вместо этого, так это написать функцию (давайте вызовем ее, convert чтобы она была короткой), которая принимает одну из ваших строк, а затем преобразует ее и возвращает timedelta объект, который вы можете сделать df['elapsed_time_new'] = df['elapsed_time'].apply(convert) , и он применит вашу convert функцию к каждой строке в вашем столбце и поместит ее вваш новый столбец. Вероятно, вы можете использовать метод, который Martijn дал в своем ответе выше, для написания такой функции.