【mimic3-benchmark详解】extract_subjects.py

# 开始有两个future——import:absolute_import和print_function。这些用于确保在不同版本python中,import语句的行为是标准化的
# 导入几个模块:
# 1、argparse:用于解析命令行参数
# 2、yaml:用于读取yaml文件
# 3、mimic3benchmark.mimic3csv:包含从csv文件加载MIMIC-III数据的函数
# 4、mimic3benchmark.util:包含用于处理MIMIC-III数据的实用函数
# 5、add_hcup_ccs_2015_groups:用于将MIMIC-III数据中的诊断编码映射到相应的HCUP(Healthcare Cost and Utilization Project)CCS(Clinical Classifications Software)分类,从而帮助研究人员对MIMIC-III数据进行分析
# 6、make_phenotype_label_matrix:用于根据MIMIC-III数据中的临床特征(如诊断和手术代码)创建一个用于训练和测试机器学习模型的标签矩阵。标签矩阵指示每个样本是否符合每个特定的临床特征。
# 这些模块中的函数可能在脚本后面被使用
# 6、最后,定义了一个名为dataframe_from_csv的函数,用于将csv文件中的数据加载到Pandas DataFrame中。该函数从mimic3benchmark.util中被导入
from __future__ import absolute_import
from __future__ import print_function

import argparse
import yaml

from mimic3benchmark.mimic3csv import *
from mimic3benchmark.preprocessing import add_hcup_ccs_2015_groups, make_phenotype_label_matrix
from mimic3benchmark.util import dataframe_from_csv

# 接下来这一段代码用来解析命令执行次数。用python内部设置的argparse模块,让用户可以在运行脚本时通过命令执行传送次数
# 调用argparse.ArgumentParser()创建了一个ArgumentParser对象,用于存储和解析命令执行参数。description是对脚本功能的简单描述。然后使用add_argument()方法为ArgumentParser对象添加多个参数
parser = argparse.ArgumentParser(description='Extract per-subject data from MIMIC-III CSV files.')#从mimic-iii csv文件中提取每个主题的数据
parser.add_argument('mimic3_path', type=str, help='Directory containing MIMIC-III CSV files.') # 必须的位置参数,用于指定文件位置
parser.add_argument('output_path', type=str, help='Directory where per-subject data should be written.') # 必须的位置参数,用于指定输出文件位置
parser.add_argument('--event_tables', '-e', type=str, nargs='+', help='Tables from which to read events.', 
                    default=['CHARTEVENTS', 'LABEVENTS', 'OUTPUTEVENTS']) # 用于指定要读取事件的表格名称,默认情况下读取如上三个
parser.add_argument('--phenotype_definitions', '-p', type=str,
                    default=os.path.join(os.path.dirname(__file__), '../resources/hcup_ccs_2015_definitions.yaml'),
                    help='YAML file with phenotype definitions.') # 一个包含确定存储疾病定义的YAML文件的路径,默认../resources/hcup_ccs_2015_definitions.yaml
parser.add_argument('--itemids_file', '-i', type=str, help='CSV containing list of ITEMIDs to keep.') #一个包含要保留的ITEMIDs列表的CSV文件的路径
parser.add_argument('--verbose', '-v', dest='verbose', action='store_true', help='Verbosity in output') #一个布尔参数,控制是否在输出中打印详细信息,默认为true
parser.add_argument('--quiet', '-q', dest='verbose', action='store_false', help='Suspend printing of details') #一个布尔参数,控制是否在输出中禁止打印详细信息,默认为false
parser.set_defaults(verbose=True)
parser.add_argument('--test', action='store_true', help='TEST MODE: process only 1000 subjects, 1000000 events.') #一个布尔值参数,控制是不是在测试模型下运行脚本,只处理1000个subject,和1000000个事件
args, _ = parser.parse_known_args() # 该方法将借些命令执行参数,并将结果返回到args中,其中,_变量用来存储不需要的参数(这里不用第二个返回值)

# 检查args.output_path指定的路径是否存在,如果不存在则pass
try:
    os.makedirs(args.output_path)
except:
    pass

# 读取patients,admitssions和icustays表格。
patients = read_patients_table(args.mimic3_path)
admits = read_admissions_table(args.mimic3_path)
stays = read_icustays_table(args.mimic3_path)
# 这行代码用于在命令行中打印一些程序运行的状态信息,例如数据处理过程中每个阶段的数据维度等。如果命令行参数 --verbose 被设置为 True,这行代码会打印出 ICU stay 表中不同 ICUSTAY_ID、HADM_ID 和 SUBJECT_ID 的数量。其中, stays.ICUSTAY_ID.unique().shape[0] 代表不同 ICUSTAY_ID 的数量,stays.HADM_ID.unique().shape[0]代表不同 HADM_ID 的数量,stays.SUBJECT_ID.unique().shape[0] 代表不同 SUBJECT_ID 的数量。
if args.verbose:
    print('START:\n\tICUSTAY_IDs: {}\n\tHADM_IDs: {}\n\tSUBJECT_IDs: {}'.format(stays.ICUSTAY_ID.unique().shape[0],
          stays.HADM_ID.unique().shape[0], stays.SUBJECT_ID.unique().shape[0]))

stays = remove_icustays_with_transfers(stays) # 删除有转移记录的ICU住院记录
# 如果传入的参数args中设置了verbose为True,则会输出当前代码块的处理结果。其中会输出当前stays表中不同的ICUSTAY_ID、HADM_ID和SUBJECT_ID的数量。
if args.verbose:
    print('REMOVE ICU TRANSFERS:\n\tICUSTAY_IDs: {}\n\tHADM_IDs: {}\n\tSUBJECT_IDs: {}'.format(stays.ICUSTAY_ID.unique().shape[0],
          stays.HADM_ID.unique().shape[0], stays.SUBJECT_ID.unique().shape[0]))

stays = merge_on_subject_admission(stays, admits) #merge_on_subject_admission()函数使用SUBJECT_ID和HADM_ID列作为共同的键,将入院表与停留表合并
stays = merge_on_subject(stays, patients) #merge_on_subject()函数使用SUBJECT_ID作为共同键,将上一步的结果表与患者表合并
stays = filter_admissions_on_nb_icustays(stays) #过滤掉具有多个ICU停留记录的入院记录
if args.verbose:
    print('REMOVE MULTIPLE STAYS PER ADMIT:\n\tICUSTAY_IDs: {}\n\tHADM_IDs: {}\n\tSUBJECT_IDs: {}'.format(stays.ICUSTAY_ID.unique().shape[0],
          stays.HADM_ID.unique().shape[0], stays.SUBJECT_ID.unique().shape[0]))

stays = add_age_to_icustays(stays) #stays 表中添加了年龄特征
stays = add_inunit_mortality_to_icustays(stays) #向stays 表中添加了入ICU时的死亡信息
stays = add_inhospital_mortality_to_icustays(stays)#向stays表中添加了住院期间死亡的信息
stays = filter_icustays_on_age(stays)# 对stays表中的ICUstay进行过滤,只保留年龄在一定范围内的ICUstay

#过滤掉年龄小于18岁的患者,并将经过处理的stays和相应的ICD诊断信息保存到csv文件中。同时,它会调用一个名为“count_icd_codes”的函数来计算不同ICD诊断代码出现的频率,并将结果保存到csv文件中。如果传入的参数args.verbose为True,它还会打印出处理后的数据集中不同ICUSTAY_ID、HADM_ID和SUBJECT_ID的数量。
if args.verbose:
    print('REMOVE PATIENTS AGE < 18:\n\tICUSTAY_IDs: {}\n\tHADM_IDs: {}\n\tSUBJECT_IDs: {}'.format(stays.ICUSTAY_ID.unique().shape[0],
          stays.HADM_ID.unique().shape[0], stays.SUBJECT_ID.unique().shape[0]))

stays.to_csv(os.path.join(args.output_path, 'all_stays.csv'), index=False)
diagnoses = read_icd_diagnoses_table(args.mimic3_path)
diagnoses = filter_diagnoses_on_stays(diagnoses, stays)
diagnoses.to_csv(os.path.join(args.output_path, 'all_diagnoses.csv'), index=False)
count_icd_codes(diagnoses, output_path=os.path.join(args.output_path, 'diagnosis_counts.csv'))

# 这两行代码用于创建疾病表型标签。首先,add_hcup_ccs_2015_groups()函数将ICD诊断编码映射到针对该诊断的HCUP CCS疾病组,返回一个新的数据帧,其中包括所有ICD诊断编码、诊断描述和相应的HCUP CCS组。然后,make_phenotype_label_matrix()函数基于疾病表型定义文件和诊断数据框生成表型标签矩阵。最终,该矩阵将保存在名为“phenotype_labels.csv”的文件中,其路径为args.output_path。
phenotypes = add_hcup_ccs_2015_groups(diagnoses, yaml.load(open(args.phenotype_definitions, 'r')))
make_phenotype_label_matrix(phenotypes, stays).to_csv(os.path.join(args.output_path, 'phenotype_labels.csv'),
                                                      index=False, quoting=csv.QUOTE_NONNUMERIC)

# 这段代码中,首先检查是否设置了测试标志args.test,如果是则对数据进行采样。
# 对于patients表格,随机选择1000个患者的数据,保留采样后的结果。
# 对于stays表格,将SUBJECT_ID列与采样后的patients表格合并,保留采样后的结果。
# 同时,将事件表格args.event_tables中除了第一个表格之外的所有表格删除,仅保留第一个表格。最后打印采样后的样本量和仅保留的事件表格名。
if args.test:
    pat_idx = np.random.choice(patients.shape[0], size=1000)
    patients = patients.iloc[pat_idx]
    stays = stays.merge(patients[['SUBJECT_ID']], left_on='SUBJECT_ID', right_on='SUBJECT_ID')
    args.event_tables = [args.event_tables[0]]
    print('Using only', stays.shape[0], 'stays and only', args.event_tables[0], 'table')

#这段代码将MIMIC-III数据集中的ICU信息、病人信息、诊断信息、事件信息等按照每个病人的SUBJECT_ID拆分为不同的文件。具体步骤如下:
#1、使用stays表中的SUBJECT_ID获取所有独立的病人ID。
#2、将stays表按照病人ID拆分为不同的文件,每个文件包含一个病人的所有ICU记录。
#3、将phenotypes表按照病人ID拆分为不同的文件,每个文件包含一个病人的所有诊断记录。
#4、如果给定了itemids_file文件,将其中的ITEMID提取出来并保存在items_to_keep变量中。
#5、遍历所有的event_tables,将每个表按照病人ID拆分为不同的文件,每个文件包含一个病人的所有事件记录。在拆分的过程中,可以使用items_to_keep变量指定需要保留的ITEMID。

# 将所有 ICU stays 和 diagnosis 数据按照 SUBJECT_ID 进行分割并输出到不同的文件中,以便更好地进行数据管理和分析。
subjects = stays.SUBJECT_ID.unique() #用stays表的SUBJECT_ID列获取唯一的SUBJECT_ID 值,并将其存储在subjects变量中
break_up_stays_by_subject(stays, args.output_path, subjects=subjects) # 调用 break_up_stays_by_subject() 函数将stays表按照SUBJECT_ID分割成多个表,并将它们写入 args.output_path 中的不同文件中
break_up_diagnoses_by_subject(phenotypes, args.output_path, subjects=subjects) #调用 break_up_diagnoses_by_subject() 函数将diagnoses表按照SUBJECT_ID分割成多个表,并将它们写入args.output_path中的不同文件中
# 这段代码循环遍历了 args.event_tables 列表中的每个元素,调用了 read_events_table_and_break_up_by_subject 函数,将每个事件表按照 SUBJECT_ID 列分割成不同的文件,并将结果保存到输出路径中。如果提供了 args.itemids_file 文件,则会将其转换为 items_to_keep 集合,并只保留集合中包含的ITEMID。最后,只处理与主题有关的文件,即 subjects_to_keep 列表中的病人的事件。
items_to_keep = set(
    [int(itemid) for itemid in dataframe_from_csv(args.itemids_file)['ITEMID'].unique()]) if args.itemids_file else None 
for table in args.event_tables:
    read_events_table_and_break_up_by_subject(args.mimic3_path, table, args.output_path, items_to_keep=items_to_keep,
                                              subjects_to_keep=subjects)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值