pandas - группировка и агрегирование последовательных строк с одинаковым значением в столбце - PullRequest
1 голос
/ 17 января 2020

У меня есть pandas DataFrame из длинного списка диапазонов даты и времени, извлеченных из базы данных, каждый диапазон с меткой. Даты упорядочены таким образом, что начальная дата одной строки является конечной датой предыдущей строки. Вот рабочий пример:

import pandas as pd

bins = [{'start': '2020-01-12 00:00:00', 'end': '2020-01-13 00:00:00', 'label': 't3'},
        {'start': '2020-01-13 00:00:00', 'end': '2020-01-13 07:00:00', 'label': 't2'},
        {'start': '2020-01-13 07:00:00', 'end': '2020-01-13 15:30:00', 'label': 't1'},
        {'start': '2020-01-13 15:30:00', 'end': '2020-01-14 00:00:00', 'label': 't2'},
        {'start': '2020-01-14 00:00:00', 'end': '2020-01-14 07:00:00', 'label': 't2'},
        {'start': '2020-01-14 07:00:00', 'end': '2020-01-14 15:30:00', 'label': 't1'},
        {'start': '2020-01-14 15:30:00', 'end': '2020-01-15 00:00:00', 'label': 't2'},
        {'start': '2020-01-15 00:00:00', 'end': '2020-01-15 07:00:00', 'label': 't2'},
        {'start': '2020-01-15 07:00:00', 'end': '2020-01-15 15:30:00', 'label': 't1'},
        {'start': '2020-01-15 15:30:00', 'end': '2020-01-16 00:00:00', 'label': 't2'},
        {'start': '2020-01-16 00:00:00', 'end': '2020-01-16 07:00:00', 'label': 't2'},
        {'start': '2020-01-16 07:00:00', 'end': '2020-01-16 15:30:00', 'label': 't1'},
        {'start': '2020-01-16 15:30:00', 'end': '2020-01-17 00:00:00', 'label': 't2'},
        {'start': '2020-01-17 00:00:00', 'end': '2020-01-17 07:00:00', 'label': 't2'},
        {'start': '2020-01-17 07:00:00', 'end': '2020-01-17 15:30:00', 'label': 't1'},
        {'start': '2020-01-17 15:30:00', 'end': '2020-01-18 00:00:00', 'label': 't2'},
        {'start': '2020-01-18 00:00:00', 'end': '2020-01-19 00:00:00', 'label': 't2'}]
bins_df = pd.DataFrame(bins)

Обратите внимание, что некоторые метки повторяются последовательно, например, 4-я и 5-я строки имеют одинаковую метку. Таким образом, метка 't2' применяется к диапазону от 2020-01-13 15:30:00 до 2020-01-14 07:00:00. Используя pandas, как я могу сгруппировать / агрегировать последовательные строки с одной и той же меткой и взять минимум start и максимум end для объединения последовательных диапазонов дат с одной и той же меткой?

1 Ответ

2 голосов
/ 17 января 2020

Сначала мы используем Series.shift с Series.cumsum, чтобы создать индикатор группы для каждого последовательного значения label.

Затем мы используем groupby.agg с min и max.

label_groups = bins_df['label'].ne(bins_df['label'].shift()).cumsum()

df = (
    bins_df.groupby(label_groups).agg({'start':'min', 'end':'max', 'label':'first'})
           .reset_index(drop=True)
)
                 start                 end label
0  2020-01-12 00:00:00 2020-01-13 00:00:00    t3
1  2020-01-13 00:00:00 2020-01-13 07:00:00    t2
2  2020-01-13 07:00:00 2020-01-13 15:30:00    t1
3  2020-01-13 15:30:00 2020-01-14 07:00:00    t2
4  2020-01-14 07:00:00 2020-01-14 15:30:00    t1
5  2020-01-14 15:30:00 2020-01-15 07:00:00    t2
6  2020-01-15 07:00:00 2020-01-15 15:30:00    t1
7  2020-01-15 15:30:00 2020-01-16 07:00:00    t2
8  2020-01-16 07:00:00 2020-01-16 15:30:00    t1
9  2020-01-16 15:30:00 2020-01-17 07:00:00    t2
10 2020-01-17 07:00:00 2020-01-17 15:30:00    t1
11 2020-01-17 15:30:00 2020-01-19 00:00:00    t2
...