pandas DataFrame高效过滤及melt宽转长实现方法
UK Biobank宽表转长表高效实现方案
直接用pandas原生宽转长接口一次性完成转换,不需要逐实例过滤、拆分拼接,同时兼容单测量项、多测量项场景,性能远高于逐实例循环处理的写法。
核心实现代码
import pandas as pd # 示例数据(已加入多测量项测试列,可直接替换为真实数据集) data = {'id': ['1', '2', '3', '4'], '3-0.0': [20, 21, 19, 18], '3-1.0': [10, 11, 29, 12], '3-2.0': [5, 6, 7, 8], '4-0.0': [120, 121, 119, 118], '4-1.0': [110, 111, 129, 112], '4-2.0': [105, 106, 107, 108]} df = pd.DataFrame(data) # 一次性完成宽转长+字段提取 fin = df.melt( id_vars="id", var_name="raw_col", value_name="measure" ).assign( # 按UK Biobank列名规则<测量项ID>-<实例号>.<数组索引>拆分字段 measure_id = lambda x: x["raw_col"].str.split("-").str[0], instance = lambda x: x["raw_col"].str.split("-").str[1].str.split(".").str[0].astype(int) ).drop(columns=["raw_col"])
方案说明
- 单测量项场景下,只需在最后
drop的列列表中加入measure_id,即可得到需要的id/measure/instance三列结构,排序后和目标结果完全一致 - 多测量项场景下,保留的
measure_id列可直接区分不同测量指标,无需修改代码即可自动适配所有符合UK Biobank命名规则的字段列 - 性能优势:全程只做一次表结构转换,没有逐列过滤、多次拼接的额外开销,数据量越大效率提升越明显
- 兼容扩展:如果存在缺失值,直接在转换链末尾加
.dropna(subset=["measure"])即可完成空值过滤;如果有性别、年龄等不需要转长的固定字段,直接加到id_vars参数列表中即可
输出示例(单测量项场景)
| id | measure | instance |
|---|---|---|
| 1 | 20 | 0 |
| 1 | 10 | 1 |
| 1 | 5 | 2 |
| 2 | 21 | 0 |
| 2 | 11 | 1 |
| 2 | 6 | 2 |
| 3 | 19 | 0 |
| 3 | 29 | 1 |
| 3 | 7 | 2 |
| 4 | 18 | 0 |
| 4 | 12 | 1 |
| 4 | 8 | 2 |
内容的提问来源于stack exchange,提问作者lmmjrf
相关产品推荐
相关产品推荐

