Отметьте «поездки» во временных рядах, используя: groupby idcolumn и cumum of timedelta - PullRequest
0 голосов
/ 13 мая 2018

У меня есть датафрейм, который выглядит примерно так:

    carid                 timestamp             speed       brake,....
0   00056f66da29e6b615aa  2017-07-18 03:46:15   NaN 0.0
1   00056f66da29e6b615aa  2017-07-18 03:46:20   0.842667    0.5
2   00056f66da29e6b615aa  2017-07-18 03:46:25   6.704000    0.5
3   00056f66da29e6b615aa  2017-07-18 03:46:30   11.746000   NaN
4   00056f66da29e6b615aa  2017-07-18 03:46:35   NaN 0.5
5   00056f66da29e6b615aa  2017-07-18 03:46:40   16.961000   NaN
6   00056f66da29e6b615aa  2017-07-19 03:46:45   11.832000   0.5
7   00056f66da29e6b615aa  2017-07-19 03:46:50   22.741333   NaN

Данные сортируются по кариду, а затем по метке времени. Я хочу добавить столбец, который добавляет идентификатор поездки, чтобы для каждой строки, имеющей одинаковый идентификатор автомобиля, а предыдущая строка отличалась не более чем на 5 секунд от предыдущей, чтобы они получали один и тот же идентификатор; строки 0-6 должны получить идентификатор 0, строки 6-7 должны получить идентификатор 1 и т. д.

Что-то вроде

(df.timestamp.diff(1).astype(int) > 5000000000).astype(int).cumsum()

, кажется, делает эту работу, если в кадре был только один кариес, но я не знаю, как его дифференцировать на кариде.

edit: как указал @RafaelC, мой образец данных не соответствует моему описанию, я обновил таблицу.

Ответы [ 2 ]

0 голосов
/ 13 мая 2018

Если вас интересуют уникальные идентификаторы, вы можете использовать | ('или') оператор с двумя conds (это было то, что я вместе с кем-то еще ответил где-то еще, но я не могу его найти)

import pandas as pd 

data = '''\
carid                 timestamp             speed       brake
00056f66da29e6b615aa  2017-07-18T03:45:15   NaN         0.0
00056f66da29e6b615aa  2017-07-18T03:46:15   0.842667    0.5
00056f66da29e6b615aa  2017-07-18T03:46:20   6.704000    0.5
00056f66da29e6b615aa  2017-07-18T03:46:25   11.746000   NaN
00056f66da29e6b615aa  2017-07-18T03:46:35   NaN         0.5
00056f66da29e6b615aa  2017-07-18T03:46:40   16.961000   NaN
00056f66da29e6b615ab  2017-07-19T03:46:50   11.832000   0.5
00056f66da29e6b615ab  2017-07-19T03:46:55   22.741333   NaN'''

df = pd.read_csv(pd.compat.StringIO(data), sep='\s+', parse_dates=['timestamp'])

Альтернатива 1 : без сброса

cond1 = df.timestamp.diff().dt.total_seconds().gt(5)
cond2 = df.carid != df.carid.shift(1)

df['uid'] = (cond1 | cond2).cumsum()

print(df)

Возвращает:

                  carid           timestamp      speed  brake  uid
0  00056f66da29e6b615aa 2017-07-18 03:45:15        NaN    0.0    1
1  00056f66da29e6b615aa 2017-07-18 03:46:15   0.842667    0.5    2
2  00056f66da29e6b615aa 2017-07-18 03:46:20   6.704000    0.5    2
3  00056f66da29e6b615aa 2017-07-18 03:46:25  11.746000    NaN    2
4  00056f66da29e6b615aa 2017-07-18 03:46:35        NaN    0.5    3
5  00056f66da29e6b615aa 2017-07-18 03:46:40  16.961000    NaN    3
6  00056f66da29e6b615ab 2017-07-19 03:46:50  11.832000    0.5    4
7  00056f66da29e6b615ab 2017-07-19 03:46:55  22.741333    NaN    4

Альтернатива 2 : Сброс (Пытался улучшить код (сократить), но голова застряла)

y = []
for _, dfx in df.groupby('carid'):
    x = dfx.timestamp.diff().dt.total_seconds().gt(5).cumsum() +1
    y.extend(x)

df['uid'] = y

print(df)

Возвращает:

                  carid           timestamp      speed  brake  uid
0  00056f66da29e6b615aa 2017-07-18 03:45:15        NaN    0.0    1
1  00056f66da29e6b615aa 2017-07-18 03:46:15   0.842667    0.5    2
2  00056f66da29e6b615aa 2017-07-18 03:46:20   6.704000    0.5    2
3  00056f66da29e6b615aa 2017-07-18 03:46:25  11.746000    NaN    2
4  00056f66da29e6b615aa 2017-07-18 03:46:35        NaN    0.5    3
5  00056f66da29e6b615aa 2017-07-18 03:46:40  16.961000    NaN    3
6  00056f66da29e6b615ab 2017-07-19 03:46:50  11.832000    0.5    1
7  00056f66da29e6b615ab 2017-07-19 03:46:55  22.741333    NaN    1
0 голосов
/ 13 мая 2018

IIUC, ваше описание не соответствует ожидаемому результату.Я не уверен, что это то, что вы хотите, но я попробую:

from datetime import timedelta 
(df.groupby("carid").timestamp.diff() > timedelta(seconds=5)).astype(int).cumsum()

0    0
1    1
2    1
3    1
4    2
5    2
6    3
7    3
6    3
7    3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...