基于patientcode行子集从两个旧变量生成新变量的实现方法
Pandas 向量化批量实现方案
针对300行规模数据集批量生成32个同规则新变量的需求,直接使用Pandas向量化操作实现,无逐行遍历的性能损耗,规则配置灵活、复用成本极低。
核心逻辑
- 将患者编码与取值来源的映射规则独立为配置项,后续调整患者分组无需修改核心计算代码
- 基于
numpy.select做批量条件赋值,远快于逐行/逐变量循环判断,当前数据规模下毫秒级完成计算 - 抽离单变量生成逻辑,仅需配置新旧变量的对应关系,即可一次性生成所有目标变量
可复用代码
import pandas as pd import numpy as np # ============================================== # 配置区:所有规则调整仅需修改这部分内容 # ============================================== # 患者分组配置:key为数据来源标识,value为对应归属的患者编码集合 patient_group = { "take_old1": {"H01", "H02", "H04"}, # 该组患者取*_Old_1类变量的取值 "take_old2": {"H03", "H05"} # 该组患者取*_Old_2类变量的取值 } # 新老变量映射配置:key为待生成的新变量名,value为(第一来源旧变量名, 第二来源旧变量名) # 生成32个新变量时,直接在字典中补充32组对应关系即可 var_map = { "Var_new": ("Var_Old_1", "Var_Old_2"), # 示例:新增第二个变量按如下格式追加即可 # "Var_new_2": ("Var_Old_1_2", "Var_Old_2_2"), # ... 补全全部32组映射 } # ============================================== # 核心计算逻辑:常规使用无需修改 # ============================================== # 生成患者来源临时标记列 df["_source_flag"] = np.select( [ df["patientcode"].isin(patient_group["take_old1"]), df["patientcode"].isin(patient_group["take_old2"]) ], ["take_old1", "take_old2"], default=pd.NA # 未匹配到分组的行默认赋值为空,可按需修改默认值 ) # 批量生成所有目标新变量 for new_col, (old_col1, old_col2) in var_map.items(): df[new_col] = np.select( [df["_source_flag"] == "take_old1", df["_source_flag"] == "take_old2"], [df[old_col1], df[old_col2]], default=pd.NA ) # 删除临时标记列 df.drop(columns=["_source_flag"], inplace=True)
结果验证
用给出的样例数据运行上述代码,输出结果完全匹配规则示例:
| patientcode | Var_Old_1 | Var_Old_2 | Var_new |
|---|---|---|---|
| H01 | 1.1 | 2.1 | 1.1 |
| H02 | 1.2 | 2.2 | 1.2 |
| H03 | 1.3 | 2.3 | 2.3 |
| H04 | 1.4 | 2.4 | 1.4 |
| H05 | 1.5 | 2.5 | 2.5 |
使用提示
- 调整患者分组时,仅需修改
patient_group中的编码集合,无需改动计算逻辑 - 新增/修改变量映射时,仅需维护
var_map字典即可,无需重复编写条件判断代码 - 底层为向量化计算实现,后续数据集规模扩大到十万级也可秒级完成计算
内容的提问来源于stack exchange,提问作者Verena
相关产品推荐
相关产品推荐

