如何简化Pandas中ICD10诊断码分组代码:条件存列表复用
问题
我已通过Pandas DataFrame创建了一组针对ICD10诊断码(Mr_Diag_Icd10_Code)的筛选条件,代码如下:
cat_A100 = df['Mr_Diag_Icd10_Code'].str.startswith(('A','B')) sub_A101 = df['Mr_Diag_Icd10_Code'].str.startswith(tuple([f"A0{i}" for i in range(9)])) sub_A102 = df['Mr_Diag_Icd10_Code'].str.startswith(tuple(["A09"])) sub_A103 = df['Mr_Diag_Icd10_Code'].str.startswith(tuple([f"A{i}" for i in range(15,20)])) | df['Mr_Diag_Icd10_Code'].str.startswith(tuple(["B90"])) sub_A104 = df['Mr_Diag_Icd10_Code'].str.startswith(tuple([f"A{i}" for i in range(40,42)])) sub_A105 = df['Mr_Diag_Icd10_Code'].str.startswith(tuple(["B24"]))
随后利用这些条件为DataFrame新增了diagcat和diagsub分类变量,代码如下:
df.loc[cat_A100, 'diagcat'] = 'A100: Certain infectious and parasitic diseases' df.loc[cat_A100 & sub_A101, 'diagsub'] = 'A101: Intestinal infectious diseases except diarrhoea' df.loc[cat_A100 & sub_A102, 'diagsub'] = 'A102: Diarrhoea and gastroenteritis of presumed infectious origin' df.loc[cat_A100 & sub_A103, 'diagsub'] = 'A103: Tuberculosis' df.loc[cat_A100 & sub_A104, 'diagsub'] = 'A104: Septicaemia' df.loc[cat_A100 & sub_A105, 'diagsub'] = 'A105: HIV disease' df.loc[cat_A100 & ~sub_A101 & ~sub_A102 & ~sub_A103 & ~sub_A104 & ~sub_A105, 'diagsub'] = 'A106: Other infectious and parasitic diseases'
我希望将这些筛选条件存入元组或列表,在生成变量时直接引用以简化代码。请问这种思路是否可行?有没有更简洁的代码实现方式?恳请提供优化建议。
优化方案
思路可行性
你的思路完全可行,将筛选规则结构化存储(如列表、字典)能显著提升代码的可读性和可维护性,避免重复编写相似逻辑。
具体简化实现
可以把每个子分类的匹配规则与对应标签整理成结构化列表,再通过numpy.select批量处理多条件赋值,大幅减少重复代码:
import pandas as pd import numpy as np # 1. 处理主分类赋值 cat_A100 = df['Mr_Diag_Icd10_Code'].str.startswith(('A', 'B')) df.loc[cat_A100, 'diagcat'] = 'A100: Certain infectious and parasitic diseases' # 2. 定义子分类规则集合:(匹配条件, 对应标签) sub_class_rules = [ # A101: 肠道感染(除腹泻) (df['Mr_Diag_Icd10_Code'].str.startswith(tuple(f"A0{i}" for i in range(9))), 'A101: Intestinal infectious diseases except diarrhoea'), # A102: 感染性腹泻肠胃炎 (df['Mr_Diag_Icd10_Code'].str.startswith("A09"), 'A102: Diarrhoea and gastroenteritis of presumed infectious origin'), # A103: 结核 (df['Mr_Diag_Icd10_Code'].str.startswith(tuple(f"A{i}" for i in range(15,20)) + ("B90",)), 'A103: Tuberculosis'), # A104: 败血症 (df['Mr_Diag_Icd10_Code'].str.startswith(tuple(f"A{i}" for i in range(40,42))), 'A104: Septicaemia'), # A105: HIV疾病 (df['Mr_Diag_Icd10_Code'].str.startswith("B24"), 'A105: HIV disease') ] # 3. 拆分条件与标签,批量赋值子分类 conditions, labels = zip(*sub_class_rules) df.loc[cat_A100, 'diagsub'] = np.select( conditions, labels, default='A106: Other infectious and parasitic diseases' )
额外优化建议
- 规则解耦:把ICD10编码规则单独抽离成配置字典(甚至外部JSON/CSV文件),后续修改分类规则时无需改动业务代码;
- 空值处理:提前对
Mr_Diag_Icd10_Code做空值填充,避免字符串方法报错:icd_codes = df['Mr_Diag_Icd10_Code'].fillna('') # 后续所有匹配逻辑改用icd_codes变量 - 扩展性:如果需要新增更多ICD10子分类,只需在
sub_class_rules列表中添加新的规则条目即可,无需修改循环或赋值逻辑。
内容的提问来源于stack exchange,提问作者sparshad
相关产品推荐
相关产品推荐

