如何使用groupby和筛选数据框架创建新列

泡沫

假设我有一个数据集,其中包含留在ICU中的患者心率的时间序列。

我想添加一些入选标准,例如,我只想考虑心率> = 90至少一小时的患者的ICU停留时间。如果一个小时后(从> = 90值开始)的第一次测量的心率未知,则我们假设该心率高于90,并计入ICU停留时间。

应该从对应“至少1小时”时间跨度的第一次测量开始,包括该ICU停留的条目。

请注意,一旦将ICU停留计入在内,即使在某个时候心率回落至90以下,也永远不会被排除。

因此,下面的数据框,其中“ Icustay”对应于在ICU中停留的唯一ID,“ Hours”指示自进入后在ICU中花费的时间

   Heart Rate  Hours  Icustay  Inclusion Criteria
0          79    0.0     1001                   0
1          91    1.5     1001                   0
2         NaN    2.7     1001                   0
3          85    3.4     1001                   0
4          90    0.0     2010                   0
5          94   29.4     2010                   0
6          68    0.0     3005                   0

应该成为

   Heart Rate  Hours  Icustay  Inclusion Criteria
0          79    0.0     1001                   0
1          91    1.5     1001                   1
2         NaN    2.7     1001                   1
3          85    3.4     1001                   1
4          90    0.0     2010                   1
5          94   29.4     2010                   1
6          68    0.0     3005                   0

我已经为此编写了代码,并且可以正常工作。但是,这非常慢,在使用我的整个数据集时,每位患者最多可能需要花费几秒钟的时间(实际上,我的数据集包含的数据比那里的6个字段还多,但为了获得更好的可读性,我对其进行了简化)。既然有4万患者,我想加快速度。

这是我当前正在使用的代码,以及上面介绍的玩具数据集。

import numpy as np
import pandas as pd

d = {'Icustay': [1001, 1001, 1001, 1001, 2010, 2010, 3005], 'Hours': [0, 1.5, 2.7, 3.4, 0, 29.4, 0],
     'Heart Rate': [79, 91, np.NaN, 85, 90, 94, 68], 'Inclusion Criteria':[0, 0, 0, 0, 0, 0, 0]}
all_records = pd.DataFrame(data=d)


for curr in np.unique(all_records['Icustay']):
    print(curr)
    curr_stay = all_records[all_records['Icustay']==curr]
    indexes = curr_stay['Hours'].index
    heart_rate_flag = False
    heart_rate_begin_time = 0
    heart_rate_begin_index = 0
    for i in indexes:
        if(curr_stay['Heart Rate'][i] >= 90 and not heart_rate_flag):
            heart_rate_flag = True
            heart_rate_begin_time = curr_stay['Hours'][i]
            heart_rate_begin_index = i
        elif(curr_stay['Heart Rate'][i] < 90):
            heart_rate_flag = False
        elif(heart_rate_flag and curr_stay['Hours'][i]-heart_rate_begin_time >= 1.0):
            all_records['Inclusion Criteria'].iloc[indexes[indexes>=heart_rate_begin_index]] = 1
            break

请注意,数据集是按患者和小时数排序的。

有没有办法加快速度?我曾经考虑过像group by这样的内置函数,但是我不确定它们在这种情况下是否会有所帮助。

这看起来有点丑陋,但它避免了循环,并且apply(基本上只是引擎盖下的循环)。我尚未在大型数据集上进行测试,但我怀疑它会比您当前的代码快很多。

首先,创建一些其他列,其中包含下一行/上一行的详细信息,因为这可能与您的某些情况有关:

all_records['PrevHeartRate'] = all_records['Heart Rate'].shift()
all_records['NextHours'] = all_records['Hours'].shift(-1)
all_records['PrevICU'] = all_records['Icustay'].shift()
all_records['NextICU'] = all_records['Icustay'].shift(-1)

接下来,创建一个包含每个id的第一条合格记录的DataFrame(由于涉及的逻辑量现在非常混乱):

first_per_id = (all_records[((all_records['Heart Rate'] >= 90) |
                            ((all_records['Heart Rate'].isnull()) & 
                            (all_records['PrevHeartRate'] >= 90) &
                            (all_records['Icustay'] == all_records['PrevICU']))) &
                            ((all_records['Hours'] >= 1) |
                            ((all_records['NextHours'] >= 1) &
                            (all_records['NextICU'] == all_records['Icustay'])))]
                .drop_duplicates(subset='Icustay', keep='first')[['Icustay']]
                .reset_index()
                .rename(columns={'index': 'first_index'}))

这给我们:

   first_index  Icustay
0            1     1001
1            4     2010

您现在可以从原始DataFrame中删除所有新列:

all_records.drop(['PrevHeartRate', 'NextHours', 'PrevICU', 'NextICU'], axis=1, inplace=True)

然后,我们可以将其与原始DataFrame合并:

new = pd.merge(all_records, first_per_id, how='left', on='Icustay')

给予:

   Heart Rate  Hours  Icustay  Inclusion Criteria  first_index
0        79.0    0.0     1001                   0          1.0
1        91.0    1.5     1001                   0          1.0
2        97.0    2.7     1001                   0          1.0
3         NaN    3.4     1001                   0          1.0
4        90.0    0.0     2010                   0          4.0
5        94.0   29.4     2010                   0          4.0
6        68.0    0.0     3005                   0          NaN

在这里,我们可以将“ first_index”(该ID的第一个合格索引)与实际索引进行比较:

new['Inclusion Criteria'] = new.index >= new['first_index']

这给出:

       Heart Rate  Hours  Icustay  Inclusion Criteria  first_index
0        79.0    0.0     1001               False          1.0
1        91.0    1.5     1001                True          1.0
2        97.0    2.7     1001                True          1.0
3         NaN    3.4     1001                True          1.0
4        90.0    0.0     2010                True          4.0
5        94.0   29.4     2010                True          4.0
6        68.0    0.0     3005               False          NaN

从这里开始,我们只需要整理一下(将结果列转换为整数,然后删除first_index列):

new.drop('first_index', axis=1, inplace=True)
new['Inclusion Criteria'] = new['Inclusion Criteria'].astype(int)

给出最终的预期结果:

       Heart Rate  Hours  Icustay  Inclusion Criteria
0        79.0    0.0     1001                   0
1        91.0    1.5     1001                   1
2        97.0    2.7     1001                   1
3         NaN    3.4     1001                   1
4        90.0    0.0     2010                   1
5        94.0   29.4     2010                   1
6        68.0    0.0     3005                   0

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

SQL:如何使用旧表和新的空列中的数据创建新表

如何在熊猫中使用groupby创建新列?

如何使用Pandas groupby和Aggregate生成新列?

根据Groupby和单独列中的值在数据框中创建新列

如何使用熊猫数据框的特定行和列来创建新系列?

如何合并数据帧、组合列和创建新行

熊猫使用groupby的计数创建新列

熊猫,使用groupby值创建新列

如何使用 dplyr 使用行数据创建新列

如何使用Powershell筛选特定的CSV数据行和列并计算总和?

如何使用pymongo创建新的数据库和集合?

如何使用 for 循环和条件语句创建新数据框

如何使用实体框架和linq使用多个groupBy列执行嵌套的组聚合函数?

使用groupBy和filter创建一个新的数据框

如何使用 Pandas 中的指定列创建新数据框?

如何使用数据透视表创建新列?

如何做groupby max在熊猫数据框中创建新列

使用熊猫数据帧如何聚合和GROUPBY和非聚集/ GROUPBY列带来

R Shiny:在反应数据框架内创建新列

如何使用mutate和for循环创建新列?

使用groupby和max(date)在窗格中创建新列

如何使用 groupby 创建具有两个关联列的新列?

从现有数据框架和索引创建新的熊猫数据框架

如何使用 if 创建新列

熊猫:如何在数据框架中创建新列并考虑其他现有列在其中添加值

如何使用数据框中的2列提取数据并使用Python创建新列?

如何在不使用框架的情况下创建/显示不同的数据数组和对象?

如何在多列上自加入一个 Pandas 数据框并创建一个带有新列的新框架(新列只有右侧的信息)

如何使用枢纽表列标题旋转到列标题和空白列的新列来使用python pandas创建数据透视表?