Последовательные отрицательные числа в кадре данных - PullRequest
0 голосов
/ 13 июня 2018

Это пример моего набора данных:

                        fvc  pef  fev1  fev1_fvc  fev6  fev25_75  fvc_changes
Date        Time                                        
2017-03-14  19:27:14    2.7  3.7  1.7   0.63      1.8   0.9         0.00
2017-03-15  11:35:21    3.1  2.8  2.0   0.65      2.2   1.2        14.81
2017-03-16  15:37:02    2.8  2.6  1.8   0.62      1.9   1.0         3.70
2017-03-17  17:11:16    2.8  3.1  1.9   0.66      2.0   1.2         3.70
2017-03-18  20:29:35    2.9  3.4  1.8   0.64      2.0   1.0         7.41
2017-03-19  21:53:09    2.2  4.1  1.5   0.65      2.2   0.8       -18.52
            21:54:23    2.4  4.1  1.7   0.71      1.8   1.2       -11.11
2017-03-20  14:36:24    2.3  4.1  1.6   0.69      1.7   1.0       -14.81
2017-03-21  22:36:43    2.1  4.0  1.4   0.63      1.4   0.8       -22.22

Это функция, которую я написал, чтобы перейти к этому этапу.

def fvc_changes(df, fvc_base=2.7):
    # for loop to calculate fvc changes from baseline
    for fvc in df:
        changes = ((df['fvc'] - fvc_base) / fvc_base) * 100
        changes = round(changes, 2)

    # add result into new column: fvc_changes
    df['fvc_changes'] = changes
    return

Я хотел бы расширить эту функциютаким образом, что:

  1. он пройдет через столбец fvc_changes (от начала до конца) и проверит, имеет ли он значение меньше -10
  2. , если он встретит третье отрицательное значение(менее -10) ПОСТОЯННО, тогда он напечатает «EXACERBATION» в новом столбце, присоединенном к тому же фрейму данных
  3. функция будет ТОЛЬКО оценивать окончательное значение fvc_changes для любой данной даты, т.е. если одна датаимеет два fvc_changes, он будет оценивать только второе значение fvc_changes

Окончательный кадр данных должен выглядеть следующим образом:

                        fvc  pef  fev1  fev1_fvc  fev6  fev25_75  fvc_changes  exacerbation
Date        Time                                        
2017-03-14  19:27:14    2.7  3.7  1.7   0.63      1.8   0.9         0.00 
2017-03-15  11:35:21    3.1  2.8  2.0   0.65      2.2   1.2        14.81
2017-03-16  15:37:02    2.8  2.6  1.8   0.62      1.9   1.0        -3.70
2017-03-17  17:11:16    2.8  3.1  1.9   0.66      2.0   1.2         3.70
2017-03-18  20:29:35    2.9  3.4  1.8   0.64      2.0   1.0         7.41
2017-03-19  21:53:09    2.2  4.1  1.5   0.65      2.2   0.8       -18.52
            21:54:23    2.4  4.1  1.7   0.71      1.8   1.2       -11.11
2017-03-20  14:36:24    2.3  4.1  1.6   0.69      1.7   1.0       -14.81
2017-03-21  22:36:43    2.1  4.0  1.4   0.63      1.4   0.8       -22.22        EXACERBATION

1 Ответ

0 голосов
/ 13 июня 2018

Я думаю, что вы можете сделать это в несколько шагов, хотя может быть более разумный способ

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              
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...