Я думаю, что вы можете сделать это в несколько шагов, хотя может быть более разумный способ
import pandas as pd
import numpy as np
df['exacerbation'] = df.groupby(level=0).fvc_changes.transform(lambda x: x.tail(1) <-10)
df['exacerbation'] = (df.groupby(df.exacerbation.astype('int').diff().abs().cumsum()).exacerbation
.apply(lambda x: x.cumsum() > 3))
df['exacerbation'] = df['exacerbation'].replace(np.NaN, False)
df['exacerbation'] = np.where(df.exacerbation, 'EXACERBATION', '')
- Первая строка создает столбец
exacerbation
и указывает, является ли последнийзначение для этого дня равно < 10
- Вторая строка определяет, существует ли полоса продолжительностью более 3 дней, когда последнее значение равно
< -10
.Обострение теперь содержит True
везде, где должно быть присвоено 'EXACERBATON'
. - Третья строка заменяет
NaN
на False
, поэтому она не интерпретируется как True
на np.where
- Четвертая строка заполняет нужные значения на основевыше логики.
Я добавил несколько строк для тестирования к вашему df
.Вот вывод
fvc_changes exacerbation
Date Time
2017-03-14 19:27:14 0.00
2017-03-15 11:35:21 14.81
2017-03-16 15:37:02 3.70
2017-03-17 17:11:16 3.70
2017-03-18 20:29:35 7.41
2017-03-19 21:53:09 -18.52
21:54:23 -11.11
2017-03-20 14:36:24 -14.81
2017-03-21 22:36:43 -22.22 EXACERBATION
2017-03-24 17:11:16 3.70
2017-03-25 20:29:35 7.41
2017-03-26 21:53:09 -18.52
2017-03-27 21:54:23 -11.11
2017-03-28 14:36:24 -14.81
2017-03-29 22:36:43 -22.22 EXACERBATION
Редактировать: Я думаю, что приведенная выше логика может быть не совсем правильной с тем, что вы хотите.Вот немного другой подход, который должен работать.Выше рассматривается несколько значений в один и тот же «день» как полоса.Этот метод учитывает только последнее значение за день в серии.Из выходных данных видно, что, хотя последние 4 строки имеют отрицательные значения, они охватывают только 2 дня, поэтому они не учитываются.
import pandas as pd
df['exacerbation'] = df.groupby(level=0).fvc_changes.transform(lambda x: x.tail(1) < -10 )
df2 = df.reset_index().drop_duplicates('Date', keep='last')
df2['exacerbation'] = (df2.groupby(df2.exacerbation.astype('int').diff().abs().cumsum()).exacerbation
.apply(lambda x: x.cumsum() >= 3))
df2['exacerbation'] = df2['exacerbation'].replace(np.NaN, False)
df = df.merge(df2[['Date', 'Time', 'exacerbation']], left_index=True, right_on=['Date', 'Time'], how='left',
suffixes=['_', '']).drop(columns='exacerbation_').set_index(['Date', 'Time']).fillna(method='bfill')
df['exacerbation'] = np.where(df.exacerbation, 'EXACERBATION', '')
Выходы:
fvc_changes exacerbation
Date Time
2017-03-14 19:27:14 0.00
2017-03-15 11:35:21 14.81
2017-03-16 15:37:02 3.70
2017-03-17 17:11:16 3.70
2017-03-18 20:29:35 7.41
2017-03-19 20:53:09 -12.52
21:53:09 -18.52
21:54:23 -11.11
2017-03-20 14:36:24 -14.81
2017-03-21 22:36:43 -22.22 EXACERBATION
2017-03-24 17:11:16 3.70
2017-03-25 20:29:35 7.41
2017-03-26 21:53:09 -18.52
2017-03-27 21:54:23 -11.11
2017-03-28 14:36:24 -14.81 EXACERBATION
2017-03-29 22:36:43 -22.22 EXACERBATION
2017-03-30 22:36:43 22.22
2017-04-02 20:53:09 -12.52
21:53:09 -18.52
21:54:23 -11.11
2017-04-03 14:36:24 -14.81