如何合并一对多关系的两个Pandas DataFrame并转为宽表
问题:合并一对多关系的DataFrame并重塑结构
原始数据
person_df1(人员信息表):
import pandas as pd person_data = [{'Id': 3763058, 'Name': 'Andi', 'description': 'abc'}, {'Id': 3763077, 'Name': 'Mark', 'description': 'xyz'}] person_df1 = pd.DataFrame(person_data)
| Id | Name | description |
|---|---|---|
| 3763058 | Andi | abc |
| 3763077 | Mark | xyz |
object_df2(人员物品表,一对多关系):
object_data = [{'Id': 3763058, 'object_name': 'PlayStation', 'object_count': 2}, {'Id': 3763077, 'object_name': 'MathsBook', 'object_count': 1}, {'Id': 3763058, 'object_name': 'MusicSystem', 'object_count': 3}, ] object_df2 = pd.DataFrame(object_data)
| Id | object_name | object_count |
|---|---|---|
| 3763058 | PlayStation | 2 |
| 3763077 | MathsBook | 1 |
| 3763058 | MusicSystem | 3 |
期望结果
将物品名称转为列,按人员Id匹配数量,无物品的填0:
| Id | Name | description | PlayStation | MathsBook | MusicSystem |
|---|---|---|---|---|---|
| 3763058 | Andi | abc | 2 | 0 | 3 |
| 3763077 | Mark | xyz | 0 | 1 | 0 |
解决方案
不用手动创建列再逐个赋值,用pandas的pivot_table透视物品表,再和人员表合并即可:
import pandas as pd # 1. 透视物品表:把object_name转成列,用object_count填充,按Id分组 object_pivot = object_df2.pivot_table( index='Id', columns='object_name', values='object_count', aggfunc='sum' # 同一个Id+物品不会重复,sum不影响结果 ).reset_index() # 2. 和人员表按Id合并,保留所有人员信息 result_df = pd.merge(person_df1, object_pivot, on='Id', how='left') # 3. 把缺失的物品数量补0,再转成整数类型 result_df = result_df.fillna(0) result_df[object_pivot.columns[1:]] = result_df[object_pivot.columns[1:]].astype(int) display(result_df)
说明
pivot_table自动生成所有唯一物品名作为列,无需手动提取列名how='left'确保所有人员信息都被保留,即使没有对应物品fillna(0)把无物品的位置补0,完全匹配需求
内容的提问来源于stack exchange,提问作者SAGY
相关产品推荐
相关产品推荐

