You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python pandas如何按ID将多行数据转换为单行多列宽表

问题说明

现有按ID维度存储的动态格式DataFrame,样例数据集df1结构如下:

df1:

ID   |Start Date|End date |claim_no|claim_type|Admission_date|Discharge_date|Claim_amt|Approved_amt
10   |01-Apr-20 |31-Mar-21|  1123  |CSHLESS   |   23-Aug-2020 | 25-Aug-2020  |   25406 | 19351 
10   |01-Apr-20 |31-Mar-21|  1212  |POSTHOSP  |   30-Aug-2020 | 01-Sep-2020  |   4209  | 3964
10   |01-Apr-20 |31-Mar-21|  1680  |CSHLESS   |   18-Mar-2021 | 23-Mar-2021  |   18002 |  0
11   |12-Dec-20 |11-Dec-21|  1503  |CSHLESS   |   12-Jan-2021 | 15-Jan-2021  |   76137 | 50286
11   |12-Dec-20 |11-Dec-21|  1505  |CSHLESS   |   05-Jan-2021 | 07-Jan-2021  |   30000 | 0

字段属性说明:

  • 静态列(每个ID取值固定):ID、Start Date、End date
  • 动态列(每个ID对应多条记录):claim_no、claim_type、Admission_date、Discharge_date、Claim_amt、Approved_amt

需求为基于ID列将所有动态字段转换为静态格式,实现每个ID仅对应单行数据,预期输出格式如下:

ID   |Start Date|End date |claim_no_1|claim_type_1|Admission_date_1|Discharge_date_1|Claim_amt_1|Approved_amt_1|claim_no_2|claim_type_2|Admission_date_2|Discharge_date_2|Claim_amt_2|Approved_amt_2|claim_no_3|claim_type_3|Admission_date_3|Discharge_date_3|Claim_amt_3|Approved_amt_3
10   |01-Apr-20 |31-Mar-21|  1123    |CSHLESS    | 23-Aug-2020     | 25-Aug-2020    |   25406   | 19351        |  1212    |POSTHOSP    | 30-Aug-2020     | 01-Sep-2020    |   4209   | 3964         |    1680  |CSHLESS     | 18-Mar-2021     | 23-Mar-2021   |   18002   | 0
11   |12-Dec-20 |11-Dec-21|  1503    |CSHLESS    | 12-Jan-2021     | 15-Jan-2021    |   76137   | 50286        |  1505    |CSHLESS     |05-Jan-2021      |07-Jan-2021     |30000     |0

此前尝试使用如下代码实现:

df1_updated = pd.get_dummies(df1,columns = ['claim_no','claim_type','Admission_date','Discharge_date','Claim_amt','Approved_amt']) 

该方案的问题是会生成数量极多的独热编码列,数据可读性极差,无法满足预期输出要求。

实现方案

pd.get_dummies的作用是生成独热编码列,完全不适配当前行转列的需求,正确实现步骤如下:

  1. 按ID分组,为每个ID下的多条动态记录生成从1开始的递增序号,作为后续展开列的后缀
    import pandas as pd
    
    # 生成组内记录序号
    df1['seq'] = df1.groupby('ID').cumcount() + 1
    
  2. 提取静态列数据,每个ID仅保留1条去重后的记录
    static_cols = ['ID', 'Start Date', 'End date']
    df_static = df1[static_cols].drop_duplicates(subset='ID')
    
  3. 以ID为行维度、序号为列维度,将所有动态列展开为宽表,并重命名列名匹配原列名_序号的格式
    dynamic_cols = ['claim_no','claim_type','Admission_date','Discharge_date','Claim_amt','Approved_amt']
    df_dynamic = df1.pivot(index='ID', columns='seq', values=dynamic_cols)
    # 重命名列
    df_dynamic.columns = [f'{col}_{seq}' for col, seq in df_dynamic.columns]
    df_dynamic = df_dynamic.reset_index()
    
  4. 将静态表和展开后的动态表按ID关联,即可得到每个ID对应单行的目标结果
    df_result = pd.merge(df_static, df_dynamic, on='ID', how='left')
    

说明:如果不同ID对应的动态记录条数不一致,展开后缺失的记录位置会自动填充空值,列数由全量数据中单个ID对应的最多动态记录数决定,不会生成冗余列,可读性完全符合要求。


内容的提问来源于stack exchange,提问作者tamil selvi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 07:12:26