Панды: извлечь час из timedelta

Этот ответ объясняет, как преобразовать целые числа в почасовые временные интервалы в Pandas. Мне нужно сделать наоборот.

Мой кадр данных df1:

   A
0  02:00:00
1  01:00:00
2  02:00:00
3  03:00:00

Мой ожидаемый кадр данных df1:

   A         B
0  02:00:00  2
1  01:00:00  1
2  02:00:00  2
3  03:00:00  3

Что я пытаюсь:

df1['B'] = df1['A'].astype(int)

Это не удается, потому что: TypeError: cannot astype a timedelta from [timedelta64[ns]] to [int32]

Как лучше всего это сделать?

ИЗМЕНИТЬ

Если я попробую df['B'] = df['A'].dt.hour, то получу: AttributeError: 'TimedeltaProperties' object has no attribute 'hour'


person FaCoffee    schedule 30.08.2018    source источник


Ответы (3)


Разделить на np.timedelta64(1, 'h'):

df1['B'] = df1['A'] / np.timedelta64(1, 'h')
print (df1)
         A    B
0 02:00:00  2.0
1 01:00:00  1.0
2 02:00:00  2.0
3 03:00:00  3.0
person jezrael    schedule 30.08.2018

Вы можете использовать dt.components и получить доступ к столбец часов:

In[7]:
df['B'] = df['A'].dt.components['hours']
df

Out[7]: 
         A  B
0 02:00:00  2
1 01:00:00  1
2 02:00:00  2
3 03:00:00  3

компоненты timedelta возвращают каждый компонент в виде столбца:

In[8]:
df['A'].dt.components

Out[8]: 
   days  hours  minutes  seconds  milliseconds  microseconds  nanoseconds
0     0      2        0        0             0             0            0
1     0      1        0        0             0             0            0
2     0      2        0        0             0             0            0
3     0      3        0        0             0             0            0
person EdChum    schedule 30.08.2018
comment
Спасибо - эта разбивка очень полезна. Мне это не нужно прямо сейчас, но я бы оставил это для других, чтобы они пригодились в будущем. - person FaCoffee; 30.08.2018
comment
Вероятно, это полезно, если кому-то нужны минуты, миллисекунды и т. д. - person EdChum; 30.08.2018

Оба решения — dt.components или np.timedelta64 — полезны. Просто np.timedelta64 намного быстрее, чем dt.components (полезно знать, особенно для больших фреймов данных):

import pandas as pd
import numpy as np

dct = { 
      'date1': ['08:05:23', '18:07:20', '08:05:23'],
      'date2': ['09:15:24', '22:07:20', '08:54:01']
      }
df = pd.DataFrame(dct)
df['date1'] = pd.to_datetime(df['date1'], format='%H:%M:%S')
df['date2'] = pd.to_datetime(df['date2'], format='%H:%M:%S')
df['delta'] = df['date2']-df['date1']

%timeit df['np_h'] = (df['delta'] / np.timedelta64(1,'h')).astype(int)
%timeit df['td_h'] = df['delta'].dt.components['hours']

Output:
1000 loops, best of 3: 484 µs per loop
1000 loops, best of 3: 1.43 ms per loop

И, как заметил @EdChum, dt.components['hours'] возвращает просто значение часов ‹ 24, что действительно не проблема в случае этого вопроса. Но для полных дат, где дельта > 24 часов, необходимо использовать dt.components['days']*24+dt.components['hours'] (что удваивает время обработки).

person Lukas    schedule 28.03.2019
comment
Я не думаю, что components выполняет умножение dt.components['days']*24. Он просто возвращает компонент hours из объекта TimedeltaProperties. - person Sam Chats; 17.04.2019