Как можно сгруппировать последовательные серии событий одного типа в DataFrame в одну строку?
Для объединения последовательных событий одного типа в один интервал в pandas можно воспользоваться методом groupby() с последующим применением функций агрегации. Например, если у нас есть DataFrame df с колонками 'event_type' и 'timestamp', и мы хотим объединить все последовательные события одного типа в один интервал, можно сделать следующим образом: ```python import pandas as pd # пример данных data = {'event_type': ['A', 'A', 'B', 'B', 'A', 'A'], 'timestamp': ['2022-01-01 01:00:00', '2022-01-01 02:00:00', '2022-01-01 03:00:00', '2022-01-01 04:00:00', '2022-01-01 05:00:00', '2022-01-01 06:00:00']} df = pd.DataFrame(data) # преобразуем столбец timestamp в datetime df['timestamp'] = pd.to_datetime(df['timestamp']) # группируем данные по event_type и создаем столбец с интервалом времени df['group'] = (df['event_type'] != df['event_type'].shift()).cumsum() # сгруппируем данные по event_type и group, найдем минимальное и максимальное значение времени result = df.groupby(['event_type', 'group']).agg({'timestamp': ['min', 'max']}).reset_index() print(result) ``` Данный код сгруппирует последовательные события одного типа в один интервал, указывая начальное и конечное время каждого интервала. Чтобы сгруппировать последовательные серии событий одного типа в DataFrame в одну строку, можно воспользоваться методом groupby() и функцией agg() с передачей словаря с агрегирующими функциями.
Давай по порядку пандас запрос который решает вопрос.
( df .assign( groups=(df['EventType'] != df['EventType'].shift()) .cumsum() ) .groupby('groups' ) .agg( first= pd.NamedAgg(column='EventTime',aggfunc=lambda x: np.min(x)), last= pd.NamedAgg(column='EventTime',aggfunc=lambda x: np.max(x)), EventType= pd.NamedAgg(column='EventType',aggfunc=lambda x: set(x).pop()), user_id=pd.NamedAgg(column='user_id',aggfunc=lambda x: set(x).pop()), ) .reset_index(drop=True) .loc[:,['user_id','EventType','first','last']] )
Ключевая история это группировка с последовательно повторяющимися значениями. Вот этот запрос по сути решает весь вопросОстальное это манипуляции для идентичного твоему вывода (писал на скорую руку совместил агрегации с трансформациями) что не есть хорошо, я бы поработал и сделал лучше. В целом сработает и для строк, но лучше привести EventTime к типу данных datetime64[ns]. Сделать это можно( df .groupby( (df["EventType"] != df["EventType"].shift()) .cumsum() ) .agg({"EventTime" : ["min", "max"]}) )
( df.assign( EventTime=lambda x: pd.to_datetime(x['EventTime'],format='%Y-%m-%d %H:%M:%S') ) ... )