如何在Pandas中按ID将唯一值映射至单独列?
Pandas实现按ID多行转单行(动态扩展列)
需求说明
原始DataFrame按ID分组,每个ID对应多条诊断记录,需要将同一ID的多条记录转为单行,为Diagnosis和Test Result分别生成带序号后缀的列,列数由各字段下条目最多的ID决定,不足的位置留空。
原始DataFrame:
| ID | Diagnosis | Test Result |
|---|---|---|
| 1 | Cancer | Positive |
| 1 | TB | Negative |
| 1 | Lupus | Indeterminate |
| 2 | Cancer | Negative |
| 2 | TB | Negative |
| 2 | Myopia | Negative |
| 2 | Hypertension | Negative |
目标DataFrame:
| ID | Diagnosis_1 | Diagnosis_2 | Diagnosis_3 | Diagnosis_4 | Test Result_1 | Test Result_2 | Test Result_3 | Test Result_4 |
|---|---|---|---|---|---|---|---|---|
| 1 | Cancer | TB | Lupus | Positive | Negative | Indeterminate | ||
| 2 | Cancer | TB | Myopia | Hypertension | Negative | Negative | Negative | Negative |
实现代码
Pandas可以通过分组生成序号+透视的方式简洁实现,具体代码如下:
import pandas as pd # 构建原始DataFrame data = { 'ID': [1,1,1,2,2,2,2], 'Diagnosis': ['Cancer', 'TB', 'Lupus', 'Cancer', 'TB', 'Myopia', 'Hypertension'], 'Test Result': ['Positive', 'Negative', 'Indeterminate', 'Negative', 'Negative', 'Negative', 'Negative'] } df = pd.DataFrame(data) # 1. 为每个ID分组内的行生成序号(从1开始) df['seq'] = df.groupby('ID').cumcount() + 1 # 2. 透视转换,将序号转为列的后缀 pivoted = df.pivot(index='ID', columns='seq') # 3. 合并多层列名,转为"字段_序号"的格式 pivoted.columns = [f'{col[0]}_{col[1]}' for col in pivoted.columns] # 4. 重置索引,将ID从索引转为列 result = pivoted.reset_index() # 可选:将空值转为空字符串 result = result.fillna('') print(result)
代码解释
- 生成序号:
groupby('ID').cumcount()为每个ID分组内的行生成从0开始的计数,加1后得到从1开始的序号,确保列后缀符合需求格式。 - 透视转换:
pivot方法将ID作为行索引,序号作为列层级,把Diagnosis和Test Result的内容展开为对应列,自动匹配最大条目数生成足够列数。 - 列名整理:将透视后的多层列名(如
('Diagnosis', 1))拼接为Diagnosis_1的格式,统一列命名规则。 - 空值处理:通过
fillna('')可将默认的NaN转为空字符串,和示例效果一致。
内容的提问来源于stack exchange,提问作者Afr0
相关产品推荐
相关产品推荐

