如何将DataFrame中的重复数据转换为指定字典结构?
解决方法
你的代码有两个关键问题导致结果不符合预期:
- 分组键错误:原数据中的
_id是单条成绩记录的唯一ID,不是学生的唯一标识,把它加入groupby会导致每个分组只有一条数据,无法合并同一学生的所有成绩。 - results结构错误:
dict(zip(group['type'], group['grade']))生成的是{类型: 分数}的字典,而你需要的是包含type和grade键的字典列表。
修正后的代码(贴近你的原始写法)
# 按学生的唯一标识分组,排除单条记录的_id grouped = df.groupby(['student_id', 'first_name', 'last_name']) transformed_data = [] # 用enumerate生成预期中的学生序号_id(从1开始) for student_idx, (group_key, group) in enumerate(grouped, start=1): group_dict = { "_id": student_idx, "student_id": group_key[0], "first_name": group_key[1], "last_name": group_key[2], # 将type和grade列转为字典列表,完全匹配你要的results格式 "results": group[['type', 'grade']].to_dict('records') } transformed_data.append(group_dict)
更简洁的pandas聚合写法
如果想减少循环,用pandas内置的聚合功能也能实现:
def format_results(group): # 将每组的type和grade转为目标字典列表 return group[['type', 'grade']].to_dict('records') # 按学生字段分组,聚合生成results列 agg_df = df.groupby(['student_id', 'first_name', 'last_name'], as_index=False).agg( results=('type', format_results) ) # 添加自增的_id列 agg_df['_id'] = agg_df.index + 1 # 调整列顺序并转为最终的字典列表 transformed_data = agg_df[['_id', 'student_id', 'first_name', 'last_name', 'results']].to_dict('records')
输出效果
运行上述代码后,transformed_data就会生成你预期的格式:
[ { '_id': 1, 'student_id': 1001, 'first_name': 'John', 'last_name': 'Doe', 'results': [ {'type': 'Project', 'grade': 5.92}, {'type': 'Oral', 'grade': 2.34}, {'type': 'Quiz', 'grade': 6.59}, {'type': 'Essay', 'grade': 9.58} ] }, { '_id': 2, 'student_id': 1002, 'first_name': 'Harry', 'last_name': 'Schmoe', 'results': [ {'type': 'Project', 'grade': 8.92}, {'type': 'Oral', 'grade': 5.94}, {'type': 'Quiz', 'grade': 4.75}, {'type': 'Essay', 'grade': 9.58} ] } ]
内容的提问来源于stack exchange,提问作者Emilia
相关产品推荐
相关产品推荐

