Вывести последовательные строки по условию Pandas

Рейтинг: -1Ответов: 1Опубликовано: 04.02.2023

Как из предоставленного DF вывести пользователей, которые совершали события в очередности: "Проснулся" => "Почистил зубы" => "Пошел на работу"?

Примерно понимаю что нужно использовать shift, но не совсем понимаю как с ним работать

d = {'Время': ['2023-01-01 00:00:00', '2023-01-01 00:00:01', '2023-01-01 00:00:01', '2023-01-01 00:00:05', '2023-01-01 00:00:07', '2023-01-01 00:00:10', '2023-01-01 00:00:18', '2023-01-01 00:00:25', '2023-01-01 00:18:00', '2023-01-01 00:20:00'],
    'Пользователь': ['Петр', 'Иван', 'Петр', 'Петр', 'Семен', 'Иван', 'Федор', 'Иван', 'Алексей', 'Игнат'],
     'Событие': ['Проснулся', 'Проснулся', 'Почистил зубы', 'Пошел на работу', 'Умылся', 'Почистил зубы', 'Умылся', 'Пошел на работу', 'Пошел на работу', 'Заснул']
    }

df = pd.DataFrame(d)

df['check_1'] = df.groupby('Пользователь')['Событие'].shift(+2)=='Проснулся'

df['check_2'] = df.groupby('Пользователь')['Событие'].shift(+1)=='Почистил зубы'

act = df.loc[(df['Событие'] == 'Пошел на работу') & (df['check_1'] == True) & (df['check_2'] == True)]

people_uniq = act.Пользователь.unique()

Почему-то результат выходит меньше ожидаемого

Ответы

▲ 1Принят

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

df = pd.DataFrame({'Индекс': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
                   'Время': ['00:00', '00:00', '00:01', '00:02', '00:03', '00:03', '00:04', '00:05', '00:06', '00:06'],
                   'Пользователь': ['Петр', 'Иван', 'Петр', 'Петр', 'Семен', 'Иван', 'Федор', 'Иван', 'Алексей',
                                    'Игнат'],
                   'Событие': ['Проснулся', 'Проснулся', 'Почистил зубы', 'Пошел на работу', 'Умылся', 'Почистил зубы',
                               'Умылся', 'Пошел на работу', 'Пошел на работу', 'Заснул']})
s = df.groupby('Пользователь')['Событие'].sum().eq('ПроснулсяПочистил зубыПошел на работу').where(lambda x: x).dropna().index.tolist()
print(s)
['Иван', 'Петр']