返回

pandas-提高函数的性能(速度)

发布时间:2022-07-15 09:35:03 272
# 数据库# 数据

我有一个患者及其结果的数据库。以下是演示数据框:

import pandas as pd
import numpy as np
from scipy.stats import linregress

data =  [[1 , '20210201', 4567, 40],
         [1 , '20210604', 4567, 55],
         [1 , '20200405', 2574, 42],
         [1 , '20210602', 2574, 55],
         [2 , '20210201', 4567, 25],
         [2 , '20210604', 4567, 32],
         [2 , '20200405', 2574, 70],
         [2 , '20210602', 2574, 46]]

df = pd.DataFrame(data, columns=['id', 'date', 'test_id', 'result'])
df.date = pd.to_datetime(df.date, format='%Y%m%d') # format date field
df

   id       date  test_id  result
0   1 2021-02-01     4567      40
1   1 2021-06-04     4567      55
2   1 2020-04-05     2574      42
3   1 2021-06-02     2574      55
4   2 2021-02-01     4567      25
5   2 2021-06-04     4567      32
6   2 2020-04-05     2574      70
7   2 2021-06-02     2574      46

data =  [[1 , '20220101'],
         [2 , '20220102']]

customers = pd.DataFrame(data, columns=['id', 'start_date'])
customers.start_date = pd.to_datetime(customers.start_date, format='%Y%m%d') # format date field
print(customers)

   id start_date
0   1 2022-01-01
1   2 2022-01-02

以及以下函数,用于获取客户及其初始日期,并返回初始日期之前特定时间段内有关每个测试的聚合结果:

def patient_agg_results(df, patient_ID, X, Y, firstAF):
    result = pd.DataFrame()
    X_date = firstAF - pd.DateOffset(months=X)
    Y_date = firstAF - pd.DateOffset(months=X+Y)
    # get results of specific patient within the timeframe
    patient_results = df[(df['id'] == patient_ID) & (df['date'] < X_date) & (df['date'] > Y_date)]  # ***
    if (len(patient_results) > 0 ):
        # Calculate mean
        curr_result = pd.DataFrame(patient_results.groupby('test_id').mean()['result'])
        curr_result = curr_result.set_index(curr_result.index.astype(str) + '_mean')
        result = pd.concat([result,curr_result])
        # Calculate newest result
        curr_result = pd.DataFrame(patient_results.groupby('test_id').max()['result'])
        curr_result = curr_result.set_index(curr_result.index.astype(str) + '_new')
        result = pd.concat([result,curr_result])
        # Calculate oldest result
        curr_result = pd.DataFrame(patient_results.groupby('test_id').min()['result'])
        curr_result = curr_result.set_index(curr_result.index.astype(str) + '_old')
        result = pd.concat([result,curr_result])
        # Calculate STD
        curr_result = pd.DataFrame(patient_results.groupby('test_id').std()['result'])
        curr_result = curr_result.set_index(curr_result.index.astype(str) + '_std')
        result = pd.concat([result,curr_result])
        # Calculate slope
        patient_results['int_date'] = pd.to_datetime(patient_results['date']).astype(np.int64) # create integer date
        curr_result = pd.DataFrame(patient_results.groupby('test_id')['result', 'int_date'].apply(lambda v: linregress(v.int_date, v.result)[0]))
        curr_result.columns = ['result']
        curr_result = curr_result.set_index(curr_result.index.astype(str) + '_slope')
        result = pd.concat([result,curr_result])
        result['id'] = patient_ID
    return result.to_dict()

我使用这样的功能:

customers['lab_results'] = customers.apply(lambda row: patient_agg_results(df,row['id'],12,12,row['start_date']),axis=1)

问题是,我的原始数据集包括大约100万名患者和数百万个结果,这需要代码运行几天。最耗时的一行是过滤行(注释:**)

你知道如何提高时间效率吗?

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(2)
按点赞数排序
用户头像