#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: добавлена возможность сделать это.