上一篇文章已经对7个txt文件做出了初步的筛选,现在借用excel来进行需要的数据筛选以及对空值的填补。(ps,其实主要就是对DEMO以及DRUG的清洗)
1.DEMO文件:(主要存储了报告信息以及病例患者的基本信息)
primaryid$caseid$caseversion$i_f_code$event_dt$mfr_dt$init_fda_dt$fda_dt$rept_cod$auth_num$mfr_num$mfr_sndr$lit_ref$age$age_cod$age_grp$sex$e_sub$wt$wt_cod$rept_dt$to_mfr$occp_cod$reporter_country$occr_country
去除对报告的客观描述后,提取需求信息如下:
primaryid$i_f_code$age$age_cod$age_grp$sex$e_sub$wt$wt_cod
主要就是年龄体重是否是首例病例,但是数据存在大量空白,以如下规则进行补缺:
1.综合age$age_cod$age_grp三项数据生成年龄段信息(ps:age有不同单位需要换算成年统一标记,同理体重字段也是)
标记规则:
N--0(新生儿):出生后28天内
I--1(婴儿):28天到1岁
C--2(儿童):2-12岁。
T--3(青少年):13-19岁
A--4(成年人):20-60岁
E--5(老年人):60岁以上
2.以是否首例,体重、性别、年龄段为关键词,利用KNN补齐缺失部分数据的报告(ps:KNN需要都是数值,str字段需要更改为对应数值,i_f_code中i记为0,f记为1,sex字段中,M记为0,F记为1)
当前数据中体重一列缺失数据约70%,如果使用KNN或其他补空,会产生比较大的噪声,所以选择利用有体重录入的数据行,对性别、年龄、是否首例进行4字段KNN补空。
补空完成后观察数据发现,年龄段和是否首例已经没有缺失值,但利用年龄段、是否首例来推测性别,前2者与后者没有关联性,所以选择用3填充剩余性别信息(约5000条),表示UNKNOW。在样本数充足的情况下或许直接删除会更好(全填充3也是便于后续直接删除)。
def fill_null_with_wt_demo(excel_path:str,excel_sheet_name:str,save_path):# 读取原始数据文件df_original = pd.read_excel(excel_path, sheet_name=excel_sheet_name)# 创建新副本用于填补age_grp和sexdf_filled = df_original.copy()# 筛选出已知的非空体重值的行df_known_weight = df_original.dropna(subset=['wt'])#选取非空体重值的3的数据df_known_values = df_known_weight[['i_f_code','age_grp', 'sex','wt']]# 使用KNNImputer拟合imputer = KNNImputer(n_neighbors=3)imputer.fit(df_known_values)
# 填补进度条with tqdm(total=len(df_known_weight)) as pbar:for i in range(len(df_known_weight)):row = df_known_weight.iloc[i]filled_values = imputer.transform([row[['i_f_code','age_grp', 'sex','wt']]])df_filled.loc[df_known_weight.index[i], ['i_f_code','age_grp', 'sex','wt']] = filled_values[0]pbar.update()
# 将填补后的数据保存到新的Excel文件df_filled.to_excel(save_path, index=False)
3.删除全部缺失数据,或只有性别的数据,总计约3W条,占比约25%,最后留余9.6W条数据