Pandas:在列高或等于0时复制数据框条目

时间:2018-06-11 09:49:14

标签: python python-3.x pandas

我有一个包含医院患者临床读数的数据框,例如类似的数据框可能看起来像这样

   heartrate  pid  time
0         67  151   0.0
1         75  151   1.2
2         78  151   2.5
3         99  186   0.0

实际上还有更多列,但我会保留这些列以使示例更简洁。

我想“扩展”数据集。简而言之,我希望能够给出一个参数n_times_back和另一个参数interval

对于每次对应for i in range (n_times_back + 1)的迭代,我们执行以下操作:

  • 创建一个新的,唯一的pid [OLD ID | i](虽然只要新的 pid对于每个重复的条目都是唯一的,确切的名称不是 对我来说非常重要,所以如果它成功的话,请随意改变它 更容易)

  • 对于每位患者(pid),请删除time列的行 超过final time of that patient - i * interval。对于 示例i * interval = 2.0以及与pid相关联的时间 是[0, 0.5, 1.5, 2.8],新时间为[0, 0.5]final time - 2.0 = 0.8

  • 迭代

因为我意识到在文本上解释这个有点乱,所以这是一个例子。

使用上面的数据集,如果我们允许n_times_back = 1interval=1,那么我们就会

   heartrate    pid  time
0         67  15100   0.0
1         75  15100   1.2
2         78  15100   2.5
3         67  15101   0.0
4         75  15101   1.2
5         99  18600   0.0

对于n_times_back = 2,结果将是

   heartrate    pid  time
0         67  15100   0.0
1         75  15100   1.2
2         78  15100   2.5
3         67  15101   0.0
4         75  15101   1.2
5         67  15102   0.0
6         99  18600   0.0

n_times_back = 3及以上会导致与n_times_back = 2相同的结果,因为没有患者数据低于该时间点

我已为此编写代码。

def expand_df(df, n_times_back, interval):
    for curr_patient in df['pid'].unique():
        patient_data = df[df['pid'] == curr_patient]
        final_time = patient_data['time'].max()
        for i in range(n_times_back + 1):
            new_data = patient_data[patient_data['time'] <= final_time - i * interval]
            new_data['pid'] = patient_data['pid'].astype(str) + str(i).zfill(2)
            new_data['pid'] = new_data['pid'].astype(int)
            #check if there is any time index left, if not don't add useless entry to dataframe
            if(new_data['time'].count()>0):
                df = df.append(new_data)
        df = df[df['pid'] != curr_patient]  # remove original patient data, now duplicate
    df.reset_index(inplace = True, drop = True)
    return df

就功能而言,此代码按预期工作。但是,它很慢。我正在使用30,000名患者的数据框,代码已经运行了2个多小时。

有没有办法使用pandas操作加快速度?我环顾四周,但到目前为止,我还没有设法用高级熊猫功能重现这个功能

1 个答案:

答案 0 :(得分:1)

最终使用groupby函数,并在没有更多时间可用时中断,以及创建&#34;索引&#34;我与&#34; pid&#34;合并的列最后一栏。

def expand_df(group, n_times, interval):
    df = pd.DataFrame()
    final_time = group['time'].max()
    for i in range(n_times + 1):
        new_data = group[group['time'] <= final_time - i * interval]
        new_data['iteration'] = str(i).zfill(2)
        #check if there is any time index left, if not don't add useless entry to dataframe
        if(new_data['time'].count()>0):
            df = df.append(new_data)
        else:
            break
    return df

new_df = df.groupby('pid').apply(lambda x : expand_df(x, n_times_back, interval))
new_df = new_df.reset_index(drop=True)
new_df['pid'] = new_df['pid'].map(str) + new_df['iteration']