对DataFrame按ID分组后应用算术与比较运算符,添加风险等级列
按ID分组并添加风险等级列的实现方案
没问题,我来帮你搞定这个需求!首先我们先构造出你提供的DataFrame,然后按ID分组,再根据自定义条件为每行添加risk列('H'代表高风险,'L'代表低风险)。
1. 构造初始DataFrame
首先我们用pandas创建你给出的数据集:
import pandas as pd data = { 'ID': [1111, 1111, 1111, 1111, 1112, 1112, 1113, 1113, 1113, 1113, 1113, 1114, 1114, 1114, 1114], 'Age': [66, 66, 66, 66, 45, 45, 78, 78, 78, 78, 78, 52, 52, 52, 52], 'Code': ['C18.2', 'C98.4', 'I50', 'D20', 'C54', 'C54', 'N18.3', 'N18.6', 'N18.2', 'N18.1', 'N18.1', 'C40', 'C19', 'C100', 'C100'] } df = pd.DataFrame(data)
2. 核心实现:分组后添加风险列
这里的关键是用groupby('ID')分组,再通过transform方法将分组判断的结果映射回原DataFrame的每一行(保证同一ID的所有行拥有相同的风险等级)。下面举几个常见的条件示例,你可以根据实际需求调整:
示例1:分组内存在恶性肿瘤编码(以'C'开头)则标记高风险
如果你的条件是只要分组里有任意一个以'C'开头的诊断码(通常代表恶性肿瘤),就标记为'H',否则为'L',可以这样写:
# 对每个ID分组,判断是否存在C开头的Code,再映射回原表 df['risk'] = df.groupby('ID')['Code'].transform( lambda x: 'H' if x.str.startswith('C').any() else 'L' )
运行后得到的结果如下:
| ID | Age | Code | risk | |
|---|---|---|---|---|
| 0 | 1111 | 66 | C18.2 | H |
| 1 | 1111 | 66 | C98.4 | H |
| 2 | 1111 | 66 | I50 | H |
| 3 | 1111 | 66 | D20 | H |
| 4 | 1112 | 45 | C54 | H |
| 5 | 1112 | 45 | C54 | H |
| 6 | 1113 | 78 | N18.3 | L |
| 7 | 1113 | 78 | N18.6 | L |
| 8 | 1113 | 78 | N18.2 | L |
| 9 | 1113 | 78 | N18.1 | L |
| 10 | 1113 | 78 | N18.1 | L |
| 11 | 1114 | 52 | C40 | H |
| 12 | 1114 | 52 | C19 | H |
| 13 | 1114 | 52 | C100 | H |
| 14 | 1114 | 52 | C100 | H |
示例2:分组内存在重复诊断码则标记高风险
如果你的条件是分组里有重复出现的诊断码,就标记为'H',可以用自定义函数实现:
def check_duplicate_codes(group): # 统计每个Code在分组内的出现次数 code_counts = group['Code'].value_counts() # 判断是否有出现次数>1的Code return 'H' if (code_counts > 1).any() else 'L' df['risk'] = df.groupby('ID')['Code'].transform(check_duplicate_codes)
这个逻辑下,ID1112(C54重复)、ID1113(N18.1重复)、ID1114(C100重复)都会被标记为'H',只有ID1111的Code无重复,标记为'L'。
示例3:组合年龄与诊断码的复杂条件
如果你的条件更复杂,比如年龄超过65岁且存在循环系统疾病编码(以'I'开头)则标记高风险,可以这样写:
def check_risk(group): # 判断分组内是否有I开头的Code has_circulatory_disease = group['Code'].str.startswith('I').any() # 同一ID的Age相同,取第一个值判断是否大于65 is_elderly = group['Age'].iloc[0] > 65 # 满足两个条件则返回'H',否则'L' return 'H' if has_circulatory_disease and is_elderly else 'L' # transform会对每个分组应用函数,返回与原表行数匹配的结果 df['risk'] = df.groupby('ID').transform(check_risk)['Code']
这个逻辑下,只有ID1111(年龄66>65,且有I50编码)会被标记为'H',其他ID都为'L'。
关键知识点总结
groupby('ID'):按ID对数据进行分组,把同一ID的行归为一组transform():将分组后的计算结果映射回原DataFrame的每一行,保证同一组的所有行得到相同的结果- 自定义条件:你可以根据需求在lambda或自定义函数中加入任意算术/比较运算,灵活调整风险判断逻辑
内容的提问来源于stack exchange,提问作者HT121
相关产品推荐
相关产品推荐

