Pandas如何循环按唯一ID重构DataFrame并新增对应列?
测试数据构造
使用以下代码生成示例DataFrame:
import pandas as pd example = { "ID": [1, 1, 2, 2, 2, 3], "place":["Maryland","Maryland", "Washington", "Washington", "Washington", "Los Angeles"], "type": ["condition", "symptom", "condition", "condition", "sky", "condition"], "name": ["depression", "cough", "fatigue", "depression", "blue", "fever" ] } example = pd.DataFrame(example)
原始数据结构预览:
目标输出
需要按唯一ID重组为宽表,预期结构如下:
result = { "ID": [1,2,3], "place":["Maryland","Washington", "Los Angeles"], "condition": ["depression", "fatigue", "fever"], "condition1":["no", "depression", "no"], "symptom": ["cough", "no", "no"], "sky": ["no", "blue", "no"] } result = pd.DataFrame(result)
目标结果预览:
重组规则
- 每个ID对应唯一的
place取值 type字段的所有唯一取值(condition、symptom、sky等)转为独立列- 同一ID下如果存在多个同type的记录,依次生成带数字后缀的列:第一个同类型列用原type名,第二个开始加数字后缀(比如第二个condition列命名为
condition1) - 没有对应取值的单元格统一填充
"no"
已尝试方案
之前通过groupby拆分数据到字典,但返回结果为字典格式,不符合宽表结构要求:
example.nunique() df_names = dict() for k, v in example.groupby('ID'): df_names[k] = v
实现代码
通过分组计数+透视表即可实现,无需写复杂嵌套循环,且支持自动适配新增的type取值:
# 给每个ID下的同type记录加序号,用于生成列名后缀 example['type_seq'] = example.groupby(['ID', 'type']).cumcount() # 生成最终列名:序号为0用原type名,大于0拼接数字后缀 example['col_name'] = example.apply( lambda x: x['type'] if x['type_seq'] == 0 else f"{x['type']}{x['type_seq']}", axis=1 ) # 透视生成宽表,空值填充为no result = example.pivot_table( index=['ID', 'place'], columns='col_name', values='name', aggfunc='first' ).reset_index().fillna('no') # 调整列顺序,固定列在前,动态生成列按名称排序 fixed_cols = ['ID', 'place'] dynamic_cols = [col for col in result.columns if col not in fixed_cols] result = result[fixed_cols + sorted(dynamic_cols)]
运行后输出结果与预期完全一致。
内容的提问来源于stack exchange,提问作者Shu
相关产品推荐
相关产品推荐

