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

如何高效将含计划、活动、项目层级关系的Pandas DataFrame转换为字典列表?

高效实现Pandas多层级DataFrame转嵌套字典列表

Hey there! Let's tackle this problem of converting your hierarchical DataFrame into that nested dictionary list structure. First, let's recap your scenario:

问题回顾

你有这样一个存储计划-活动-项目层级关系的DataFrame:

plan_idplan_nameactivity_idactivity_nameitem_iditem_name
1plan11activity11item1
1plan12activity23item3
2plan21activity11item1

目标是转换成每个计划包含下属活动、每个活动包含下属项目的嵌套字典列表,最终结构你已经明确给出。

你自己实现了一种拆分DataFrame后循环嵌套的方案:

plans_dict = plans_df.to_dict('records')
for plan in plans_dict:
    plan['activities'] = activities_df[activities_df['id']==plan['id']].to_dict('records')
    for activity in plan['activities']:
        activity['items'] = items_df[items_df['activity_id']==activity['activity_id']].to_dict('records')

这个方案在小数据量下没问题,但如果数据规模变大,多次的切片查询会带来不少性能损耗,而且Python层面的循环效率也不如Pandas的向量化操作。下面给你两种更高效的实现思路:


更优实现方案

方案1:双层GroupBy + 嵌套聚合(性能最优)

这个思路是从最底层的项目开始,逐层向上聚合,全程用Pandas的内置操作,避免显式循环:

import pandas as pd

# 假设你的原始DataFrame名为df
def get_items(group):
    # 把每个活动下的项目转换成字典列表
    return group[['item_id', 'item_name']].to_dict('records')

def get_activities(group):
    # 对每个计划下的活动分组,聚合出对应的项目列表
    activity_groups = group.groupby(['activity_id', 'activity_name']).apply(get_items).reset_index()
    activity_groups.columns = ['activity_id', 'activity_name', 'items']
    return activity_groups.to_dict('records')

# 对计划分组,聚合出对应的活动列表
plan_groups = df.groupby(['plan_id', 'plan_name']).apply(get_activities).reset_index()
plan_groups.columns = ['plan_id', 'plan_name', 'activities']

# 生成最终的嵌套字典列表
final_result = plan_groups.to_dict('records')

为什么这个更高效?

  • 全程用Pandas的GroupBy和Apply,都是C层面的优化操作,比Python循环快得多
  • 只做了两次分组操作,避免了多次切片查询的开销,数据量越大,性能提升越明显

方案2:分组后字典推导(简洁易读)

如果追求代码的简洁性和可读性,也可以用分组+字典推导的方式,虽然有循环,但循环的是分组结果(数量远少于原始数据行数):

final_result = []
# 先按计划分组
for (plan_id, plan_name), plan_data in df.groupby(['plan_id', 'plan_name']):
    activities_list = []
    # 再在每个计划内按活动分组
    for (act_id, act_name), act_data in plan_data.groupby(['activity_id', 'activity_name']):
        # 生成当前活动的项目列表
        items = act_data[['item_id', 'item_name']].to_dict('records')
        activities_list.append({
            'activity_id': act_id,
            'activity_name': act_name,
            'items': items
        })
    # 把当前计划加入结果列表
    final_result.append({
        'plan_id': plan_id,
        'plan_name': plan_name,
        'activities': activities_list
    })

这个方案比你的原始方案高效很多,因为它避免了每次循环都做一次布尔索引切片,而是直接基于分组后的子集操作,减少了不必要的数据复制。


性能对比小总结

  • 你的原始方案:时间复杂度接近O(n*m)(n为计划数,m为活动数),数据量大时会明显变慢
  • 推荐的方案:时间复杂度更接近O(n),利用Pandas的向量化操作,性能提升显著

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 06:07:30