基于Pandas实现多DataFrame按talent_id聚合:将多行重复记录转为单行多列结构
解决方案:将多对一的教育/工作经历数据宽表化并合并
我明白你想要实现的是把多对一的教育、工作经历数据转换为宽表格式,最终和主表合并后每个talent_id仅保留一行记录。不用手动遍历这么麻烦,Pandas提供了高效的向量化操作来处理这种需求,咱们一步步来实现:
核心思路
- 给每个
talent_id的多条教育/工作经历添加序号标识(比如第1条教育、第2条教育) - 将子表(df2、df3)从长表转换为宽表,把每条经历的字段转成
字段名_序号的格式(比如schoolname_1、company_2) - 用
merge将主表和转换后的宽表按talent_id关联,得到最终整合结果
完整实现代码
import pandas as pd # 1. 生成示例数据(你提供的原代码) data1 = [['001', '1975-01-01', 'mr', 'de', 'at', 40000], ['002', '1980-01-01', 'mrs', 'en', 'uk', 50000], ['003', '1985-01-01', 'mr', 'es', 'es', 45000]] df1 = pd.DataFrame(data1, columns = ['talent_id', 'birthdate', 'salutation', 'nationality', 'country', 'salary']) data2 = [['001', 'groundschool_a', 'NaN', 'basic', 'none', 'yes'], ['001', 'high_school', 'math', 'higher', 'none', 'no'], ['002', 'groundschool_b', 'NaN', 'basic', 'none', 'yes'], ['002', 'highschool', 'science', 'higher', 'yes', 'yes'], ['002', 'college', 'medicine', 'degree', 'MA', 'yes'], ['003', 'NA', 'none', 'dont know', 'none', 'NaN']] df2 = pd.DataFrame(data2, columns = ['talent_id', 'schoolname', 'subject', 'type_of_education', 'degree', 'completed']) data3 = [['001', 'company_a', 'supervisor', 'manufacturing'], ['001', 'company_b', 'editor', 'educational'], ['002', 'company_c', 'clerk', 'pos'], ['002', 'company_d', 'cleaning', 'steel'], ['002', 'company_e', 'ceo', 'sales'], ['003', 'company_f', 'it', 'retail']] df3 = pd.DataFrame(data3, columns = ['talent_id', 'company', 'position', 'industry']) # 2. 处理教育经历表df2,转换为宽表 # 给每个talent_id的教育经历添加序号(从1开始) df2['edu_seq'] = df2.groupby('talent_id').cumcount() + 1 # 转宽表:以talent_id为索引,edu_seq为列维度,其余字段为值 df2_wide = df2.pivot(index='talent_id', columns='edu_seq', values=['schoolname', 'subject', 'type_of_education', 'degree', 'completed']) # 合并多层列名为单层(比如('schoolname',1) → 'schoolname_1') df2_wide.columns = [f'{col[0]}_{col[1]}' for col in df2_wide.columns] # 重置索引,让talent_id回到普通列 df2_wide = df2_wide.reset_index() # 3. 处理工作经历表df3,转换为宽表(逻辑和df2一致) df3['work_seq'] = df3.groupby('talent_id').cumcount() + 1 df3_wide = df3.pivot(index='talent_id', columns='work_seq', values=['company', 'position', 'industry']) df3_wide.columns = [f'{col[0]}_{col[1]}' for col in df3_wide.columns] df3_wide = df3_wide.reset_index() # 4. 合并所有表:先合并主表和教育宽表,再合并工作宽表 final_df = df1.merge(df2_wide, on='talent_id', how='left') final_df = final_df.merge(df3_wide, on='talent_id', how='left') # 5. 把空值填充为'NA'(和你的理想输出格式匹配) final_df = final_df.fillna('NA') # 查看结果 print(final_df)
代码说明
groupby('talent_id').cumcount():给每个talent_id组内的行生成连续序号,+1是为了让序号从1开始更符合直观pivot():是Pandas中专门用于长表转宽表的方法,指定索引、列维度和值字段后,自动完成转换merge():因为talent_id在主表df1中是唯一的,用how='left'可以确保主表的所有记录都被保留,即使某个talent_id没有教育或工作经历
这种方法比手动遍历高效得多,尤其是当数据量较大时,Pandas的向量化操作会比循环快几个数量级,而且代码更简洁易维护,完全符合你想要的“智能、高效”的需求。
内容的提问来源于stack exchange,提问作者t.jirku
相关产品推荐
相关产品推荐

