数据框中的连续负数

时间:2018-06-13 14:39:38

标签: python function dataframe

这是我的数据集示例:

                        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的第二个值
  4. 最终数据框应如下所示:

                            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 :(得分:2)

我认为你可以通过几个步骤完成这项工作,不过可能有更聪明的方法

​​TypeError: this.store.pipe is not a function​​
  • 第一行创建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
  • 第二行确定是否存在超过3天的条纹,其中最后一个值为< 10。 Exacerbation现在包含< -10,应该在任何地方分配True
  • 第三行将'EXACERBATON'替换为NaN,因此False不会将其解释为True
  • 第四行根据上述逻辑填写所需的值。

我添加了几行用于测试np.where。这是输出

df

编辑:我认为上述逻辑可能并不完全正确。这是一个应该有效的略有不同的方法。以上考虑与条纹相同的“日”的多个值。此方法仅计算条纹中一天的最后一个值。你可以在输出中看到虽然最后4行有负值,但它们只有2天,因此不计算。

                     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

输出:

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', '')