Временная метка, timedelta и преобразование в Python

#python #datetime #timestamp #timedelta

#python #datetime #временная метка #timedelta

Вопрос:

У меня есть фрейм данных, в котором есть столбец временной метки в формате: ГГГГ-ММ-ДД ЧЧ: ММ: СС: sss. Пример показан ниже:

 0      2019-12-17 21:17:39.424
1      2019-12-17 21:17:41.065
2      2019-12-17 21:18:06.640
3      2019-12-17 21:18:07.229
4      2019-12-17 21:18:07.858
                 ...          
1072   2019-12-17 22:54:54.052
1073   2019-12-17 22:54:56.075
1074   2019-12-17 22:55:23.040
1075   2019-12-17 22:55:23.040
1076   2019-12-17 22:55:26.363
Name: time_stamp, Length: 1077, dtype: datetime64[ns]
  

существует более тысячи строк, которые я считываю из файла csv. Что я пытался найти временной интервал (timedelta) между каждой последующей временной меткой. Поскольку разница между каждой последовательной парой не превышает нескольких секунд, я просто хочу получить эту часть (отбрасывая данные, часовые и минутные части, которые в любом случае равны 0.

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

 > 0       0 days 00:00:03.988000
1       0 days 00:00:01.641000
2       0 days 00:00:25.575000
3       0 days 00:00:00.589000
4       0 days 00:00:00.629000
                 ...          
1072    0 days 00:00:36.084000
1073    0 days 00:00:02.023000
1074    0 days 00:00:26.965000
1075           0 days 00:00:00
1076    0 days 00:00:03.323000
Name: arr_time, Length: 1077, dtype: object
  

Теперь, как вы можете видеть, тип данных — string, что не позволяет мне выполнять различные операции, связанные с типом данных timedelta или datetime. Я не могу изменить его тип данных. Я настолько запутался между концепциями datetime, timestamp и timedelta, что не могу понять, какие операции или методы поддерживаются для каждого случая.

Я могу предоставить необработанный файл csv.

Может ли кто-нибудь, пожалуйста, помочь мне просто извлечь секунды и миллисекундные части каждого значения timedelta в серию или фрейм данных?

Ответ №1:

Ваши данные содержат информацию о дате / времени (например, в виде строки типа «2019-12-17T21:17:39.424») — вы анализируете это datetime , например, как

 df['time_stamp'] = pd.to_datetime(df['time_stamp'])
# gives dtype: datetime64[ns]
  

Отдельным элементом этого столбца (pd.Series) будет a Timestamp . Если вы вычтете две временные метки друг из друга, вы получите timedelta :

 # the difference between timestamps are timedeltas:
df['dt'] = df['time_stamp'].diff()
# df['dt']
# 0                      NaT
# 1   0 days 00:00:01.641000
# 2   0 days 00:00:25.575000
# 3   0 days 00:00:00.589000
# 4   0 days 00:00:00.629000
# Name: dt, dtype: timedelta64[ns]
  

Теперь, когда у вас есть столбец dtype timedelta, вы можете работать с ним, чтобы получить секунды и миллисекунды:

 # get the seconds fraction by flooring the total_seconds() of the timedelta
df['dt_s'] = np.floor(df['dt'].dt.total_seconds())
# df['dt_s']
# 0     NaN
# 1     1.0
# 2    25.0
# 3     0.0
# 4     0.0
# Name: dt_s, dtype: float64

# get the milliseconds by converting total_seconds() to milliseconds and taking modulo 1000:
df['dt_ms'] = (df['dt'].dt.total_seconds()*1000) % 1000
# df['dt_ms']
# 0      NaN
# 1    641.0
# 2    575.0
# 3    589.0
# 4    629.0
# Name: dt_ms, dtype: float64
  

При желании вы можете отформатировать секундные и миллисекундные компоненты в строковый столбец:

 # format to ss:fff output:
df['s_ms'] = (df['dt_s'].fillna(0).apply(lambda s: f'{int(s):02d}')   
              ':'   
              df['dt_ms'].fillna(0).apply(lambda s: f'{int(s):03d}'))
# df['s_ms'] 
# 0    00:000
# 1    01:641
# 2    25:575
# 3    00:589
# 4    00:629
# Name: s_ms, dtype: object
  

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

1. Большое вам спасибо. Это работает отлично. Еще один вопрос: как представить результирующие значения секунд и миллисекунд в виде [SS.mmm]? Еще раз спасибо.

2. @SaqibAlikhan: добавлена возможность сделать это.