Я предполагаю, что ваш исходный DataFrame имеет только Дата / Время (либо строка , либо datetime ), Событие ( строка ) и AbnormalState ( int ) столбцы.
Чтобы вычислить столбец группировки, запустите:
dataframe['AbnormalStateGrouping'] = dataframe.groupby(
dataframe['Event'][::-1].notnull().cumsum()).AbnormalState\
.apply(lambda grp: (grp != grp.shift()).cumsum())
Результат, для исходных исходных данных, представленных в виде изображения, это:
Date/Time Event AbnormalState AbnormalStateGrouping
0 2018-01-01 01:00 NaN 0 1
1 2018-01-01 02:00 NaN 0 1
2 2018-01-01 03:00 NaN 1 2
3 2018-01-01 04:00 NaN 1 2
4 2018-01-01 05:00 NaN 0 3
5 2018-01-01 06:00 NaN 0 3
6 2018-01-01 07:00 NaN 0 3
7 2018-01-01 08:00 NaN 1 4
8 2018-01-01 09:00 NaN 1 4
9 2018-01-01 10:00 NaN 0 5
10 2018-01-01 11:00 NaN 0 5
11 2018-01-01 12:00 NaN 0 5
12 2018-01-01 13:00 NaN 1 6
13 2018-01-01 14:00 NaN 1 6
14 2018-01-01 15:00 NaN 0 7
15 2018-01-01 16:00 Event 0 7
16 2018-01-01 17:00 NaN 1 1
17 2018-01-01 18:00 NaN 1 1
18 2018-01-01 19:00 NaN 0 2
19 2018-01-01 20:00 NaN 0 2
Обратите внимание на способ группировки:
dataframe['Event'][::-1].notnull().cumsum()
Из-за [:: - 1] , cumsum функция вычисляется от последней строки до первой. Таким образом:
- строки с часами 01: 00 через 16: 00 находятся в группе 1 ,
- оставшиеся строки (час 17: 00 через 20: 00 ) находятся в группе 0 .
Затем до AbnormalState , отдельно для каждой группы применяется лямбда-функция, поэтому каждая совокупная сумма начинается с 1 только в каждой группе (после каждого Event ) .
Редактировать после комментария от 22: 18: 12Z
Причина, по которой я вычисляю cumsum для группировки в обратном порядке , заключается в том, что когда вы запускаете его в нормальном порядке:
dataframe['Event'].notnull().cumsum()
затем:
- строк с индексом 0 через 14 (перед строкой с Event ) имеет эту сумму == 0 ,
- строка с индексом 15 , а следующие строки имеют эту сумму == 1 .
Попробуйте обе версии, без и с [:: - 1] .
* 10 94 * Результат в обычном порядке (без
[:: - 1] ) таков:
- Событие строка находится в той же группе с после строк,
- , поэтому сброс происходит только в этой строке.
Чтобы проверить весь результат, запустите мой код без [:: - 1] , и вы увидите, что конечная часть результата содержит:
Date/Time Event AbnormalState AbnormalStateGrouping
14 2018-01-01 15:00:00 NaN 0 7
15 2018-01-01 16:00:00 Event 0 1
16 2018-01-01 17:00:00 NaN 1 2
17 2018-01-01 18:00:00 NaN 1 2
18 2018-01-01 19:00:00 NaN 0 3
19 2018-01-01 20:00:00 NaN 0 3
, так что строка Event должна иметь AbnormalStateGrouping == 1 .
Но вы хотите, чтобы эта строка имела AbnormalStateGrouping в последовательности предыдущих состояний группировки (в данном случае 7 ), и сброс должен происходить из следующей строки.
Таким образом, строка Event должна быть в той же группе с предшествующей строк, каков результат моего кода.