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

如何高效将Pandas分组后的多层索引结果转为嵌套字典

问题:将多层索引Series转换为嵌套字典的高效实现

场景与需求

执行以下分组统计代码后:

df.groupby(by=["Unit","Product","Scheme","Type"]).size()

得到多层索引的Series结果:

Unit           Product       Scheme        Type
JBBNB          BP            KRZPS         MRTZN               13
                                           TOPUP                5
                                           ZBPRE                3
               HB            KRJZS         CONST                6
                                           FZNEW                5
                                                               ..
htrcy          HB            TNJZS         PZTCN                2
                             TNBTS         TOEJZ                2
               TU            TNTPS         BDDFIN               2
                                           TOPUP                1
hwrng          BP            TGZPS         ZBPRE                1
Length: 1632, dtype: int64

需要将其转换为如下结构的嵌套字典:

{
    "JBBNB": {"BP": {"KRZPS":{"MRTZN":13,"TOPUP":5,"ZBPRE":3}},
              "HB":{"KRJZS":{"CONST":6,"FZNEW":5}}
             },
    "htrcy": {"HB": {"TNJZS":{"PZTCN":2}, 
                    "TNBTS":{"TOEJZ":2}},
              "TU":{"TNTPS":{"BDDFIN":2,"TOPUP":1}},
             }
}

补充数据示例:

data = {"Unit": {"31-08": "JBJEB", "22-11": "JBGRB", "06-04": "JBGRB", "29-11": "JBZWI", "15-02": "JBGRB", "28-02": "JBJEB", "23-03": "JBGRB", "13-06": "JBJEB", "30-06": "JBMDR", "20-07": "JBJEB", "23-07": "JBJEB", "25-07": "JBJEB", "23-08": "JBJEB", "30-09": "JBZWR", "22-10": "JBJEB", "27-12": "JBJMD", "31-12": "JBJEB", "25-03": "JBJEB", "29-03": "JBJEB", "29-04": "JBJEB", "29-07": "JBJEB", "18-06": "JBJMD", "30-07": "JBMDR", "10-08": "JBJMR", "24-03": "JBJMD", "19-07": "JBJMD", "26-12": "JBJMD", "31-03": "JBJMR", "08-09": "JBJMR", "07-10": "JBJMR", "10-05": "JBJMR", "28-07": "JBJMR", "27-09": "JBJMR", "27-11": "JBJMR", "30-11": "JBJMR", "22-12": "JBJMR", "24-07": "JBZJB", "23-09": "JBZWI", "29-09": "JBZWI", "07-02": "JBZWI", "14-10": "JBZWR", "23-12": "JBZWR", "29-08": "JBZWR", "18-11": "JBZWR", "21-12": "JBZWR", "03-01": "JBZWR", "28-08": "JBZWR", "20-09": "JBMDR", "02-12": "JBMDR"}, "Product": {"31-08": "TU", "22-11": "TU", "06-04": "TU", "29-11": "TU", "15-02": "TU", "28-02": "TU", "23-03": "TU", "13-06": "TU", "30-06": "TU", "20-07": "TU", "23-07": "TU", "25-07": "TU", "23-08": "TU", "30-09": "TU", "22-10": "TU", "27-12": "TU", "31-12": "TU", "25-03": "TU", "29-03": "TU", "29-04": "TU", "29-07": "TU", "18-06": "TU", "30-07": "TU", "10-08": "TU", "24-03": "TU", "19-07": "TU", "26-12": "TU", "31-03": "TU", "08-09": "BP", "07-10": "TU", "10-05": "TU", "28-07": "TU", "27-09": "TU", "27-11": "TU", "30-11": "TU", "22-12": "TU", "24-07": "TU", "23-09": "TU", "29-09": "TU", "07-02": "TU", "14-10": "BP", "23-12": "BP", "29-08": "TU", "18-11": "TU", "21-12": "TU", "03-01": "TU", "28-08": "TU", "20-09": "TU", "02-12": "TU"}, "Scheme": {"31-08": "GJTPS", "22-11": "UPTPS", "06-04": "UPTPS", "29-11": "UKTPS", "15-02": "UPTPS", "28-02": "GJTPS", "23-03": "UPTPS", "13-06": "GJTPS", "30-06": "MJTPS", "20-07": "GJTPS", "23-07": "GJTPS", "25-07": "GJTPS", "23-08": "GJTPS", "30-09": "RJTPS", "22-10": "GJTPS", "27-12": "GJTPS", "31-12": "GJTPS", "25-03": "GJTPS", "29-03": "GJTPS", "29-04": "GJTPS", "29-07": "GJTPS", "18-06": "GJTPS", "30-07": "MJTPS", "10-08": "RJTPS", "24-03": "GJTPS", "19-07": "GJTPS", "26-12": "GJTPS", "31-03": "RJTPS", "08-09": "RJZPS", "07-10": "RJTPS", "10-05": "RJTPS", "28-07": "RJTPS", "27-09": "RJTPS", "27-11": "RJTPS", "30-11": "RJTPS", "22-12": "RJTPS", "24-07": "UPTPS", "23-09": "UKTPS", "29-09": "UKTPS", "07-02": "UKTPS", "14-10": "RJZPS", "23-12": "RJZPS", "29-08": "RJTPS", "18-11": "RJTPS", "21-12": "RJTPS", "03-01": "RJTPS", "28-08": "RJTPS", "20-09": "MJTPS", "02-12": "MJTPS"}, "Type": {"31-08": "BDDFIN", "22-11": "BDDFIN", "06-04": "BDDFIN", "29-11": "BDDFIN", "15-02": "BDDFIN", "28-02": "BDDFIN", "23-03": "BDDFIN", "13-06": "BDDFIN", "30-06": "BDDFIN", "20-07": "BDDFIN", "23-07": "BDDFIN", "25-07": "BDDFIN", "23-08": "BDDFIN", "30-09": "BDDFIN", "22-10": "BDDFIN", "27-12": "BDDFIN", "31-12": "BDDFIN", "25-03": "BDDFIN", "29-03": "BDDFIN", "29-04": "BDDFIN", "29-07": "BDDFIN", "18-06": "BDDFIN", "30-07": "BDDFIN", "10-08": "BDDFIN", "24-03": "BDDFIN", "19-07": "BDDFIN", "26-12": "BDDFIN", "31-03": "BDDFIN", "08-09": "BDDFIN", "07-10": "BDDFIN", "10-05": "BDDFIN", "28-07": "BDDFIN", "27-09": "BDDFIN", "27-11": "BDDFIN", "30-11": "BDDFIN", "22-12": "BDDFIN", "24-07": "BDDFIN", "23-09": "BDDFIN", "29-09": "BDDFIN", "07-02": "BDDFIN", "14-10": "BDDFIN", "23-12": "BDDFIN", "29-08": "BDDFIN", "18-11": "BDDFIN", "21-12": "BDDFIN", "03-01": "BDDFIN", "28-08": "BDDFIN", "20-09": "BDDFIN", "02-12": "BDDFIN"}}
df = pd.DataFrame(data)

高效实现方法

方法1:直接遍历多层索引(性能最优)

直接遍历Series的多层索引与对应值,通过dict.setdefault逐层构建嵌套字典,无额外数据转换开销,适合大数据量场景:

# 先获取分组统计结果
s = df.groupby(by=["Unit","Product","Scheme","Type"]).size()

# 初始化结果字典
result = {}

# 遍历每一组的索引和计数
for (unit, product, scheme, typ), count in s.items():
    # 逐层创建嵌套字典
    result.setdefault(unit, {}).setdefault(product, {}).setdefault(scheme, {})[typ] = count

方法2:递归构造字典(代码更规整)

如果分组层级不确定或需要灵活适配,可使用递归方法,结合DataFrame分组逻辑构建嵌套结构:

s = df.groupby(by=["Unit","Product","Scheme","Type"]).size().reset_index(name='count')

def build_nested(df, levels):
    if len(levels) == 1:
        return df.set_index(levels[0])['count'].to_dict()
    return {
        group_key: build_nested(group_df.drop(levels[0], axis=1), levels[1:])
        for group_key, group_df in df.groupby(levels[0])
    }

result = build_nested(s, ['Unit', 'Product', 'Scheme', 'Type'])

效率说明

  • 方法1在数据量较大时(如示例中的1632条数据)性能更优,直接操作索引和值,避免了DataFrame分组的额外开销。
  • 方法2代码结构更清晰,适合层级动态变化的场景,性能略逊于方法1,但差距在可接受范围内。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 04:40:19