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

如何对Pandas DataFrame按3列及以上分组,生成嵌套字典格式的子码列表?

如何对Pandas DataFrame按3列及以上分组,生成嵌套字典格式的子码列表?

嘿,我完全get到你的需求了——就是要把DataFrame里的层级关系(Region→Country→AREA_CODE)对应到子码列的嵌套字典对吧?先帮你把之前踩的groupby解包坑填上,再一步步实现你想要的嵌套结构~

先解决你之前的报错问题

你之前写的代码报错too many values to unpack (expected 2),原因很简单:当你用['Region', 'Country', 'AREA_CODE']这3列分组时,每个分组的键是一个包含3个元素的元组(比如('AMER', 'US', 'A1')),但你却用(k1, k2)来解包,自然会因为元素数量不匹配报错。正确的解包应该是(k1, k2, k3),对应3个分组列的键值。

分步实现你要的嵌套结构

首先咱们先把示例DataFrame构造出来,方便后续演示:

import pandas as pd

data = {
    'Region': ['AMER', 'AMER', 'AMER', 'AMER'],
    'Country': ['US', 'CANADA', 'US', 'US'],
    'AREA_CODE': ['A1', 'A1', 'B1', 'A1'],
    'AREA_SUB_CODE_1': ['A1_US_1', 'A1_CA_1', 'B1_US_1', 'A1_US_1'],
    'AREA_SUB_CODE_2': ['A1_US_2', 'A1_CA_2', 'B1_US_2', 'A1_US_2']
}
df = pd.DataFrame(data)

1. 生成AREA_SUB_CODE_1的嵌套字典

按照你要的结构,我们需要按Region→Country→AREA_CODE层级分组,提取每个层级下AREA_SUB_CODE_1的唯一值列表:

result = {'AREA_SUB_CODE_1': {}}

# 按3列分组,解包时对应3个键值
for (region, country, area_code), sub_codes in df.groupby(['Region', 'Country', 'AREA_CODE'])['AREA_SUB_CODE_1']:
    # 逐层创建嵌套字典,确保每个层级的键存在
    if region not in result['AREA_SUB_CODE_1']:
        result['AREA_SUB_CODE_1'][region] = {}
    if country not in result['AREA_SUB_CODE_1'][region]:
        result['AREA_SUB_CODE_1'][region][country] = {}
    # 存入去重后的子码列表
    result['AREA_SUB_CODE_1'][region][country][area_code] = sub_codes.unique().tolist()

运行后result['AREA_SUB_CODE_1']的结构就完全符合你的要求:

{
    "AMER": {
        "US": {
            "A1": ["A1_US_1"],
            "B1": ["B1_US_1"]
        },
        "CANADA": {
            "A1": ["A1_CA_1"]
        }
    }
}

2. 生成AREA_SUB_CODE_2的嵌套字典

你对AREA_SUB_CODE_2的要求多了一层:在AREA_CODE下面还要关联AREA_SUB_CODE_1,所以需要按Region→Country→AREA_CODE→AREA_SUB_CODE_1这4列分组:

result['AREA_SUB_CODE_2'] = {}

# 按4列分组,解包对应4个键值
for (region, country, area_code, sub1_code), sub2_codes in df.groupby(['Region', 'Country', 'AREA_CODE', 'AREA_SUB_CODE_1'])['AREA_SUB_CODE_2']:
    # 逐层构建嵌套
    if region not in result['AREA_SUB_CODE_2']:
        result['AREA_SUB_CODE_2'][region] = {}
    if country not in result['AREA_SUB_CODE_2'][region]:
        result['AREA_SUB_CODE_2'][region][country] = {}
    if area_code not in result['AREA_SUB_CODE_2'][region][country]:
        result['AREA_SUB_CODE_2'][region][country][area_code] = {}
    # 存入去重后的AREA_SUB_CODE_2列表
    result['AREA_SUB_CODE_2'][region][country][area_code][sub1_code] = sub2_codes.unique().tolist()

这部分运行后就会得到你想要的多层嵌套结构,比如US的A1下面会有"A1_US_1": ["A1_US_2"]这样的对应关系。

用通用函数优化代码(可选)

如果以后还要处理更多类似的子码列,写一个通用函数会更高效,不管是3列还是5列分组都能搞定:

def build_nested_dict(df, target_col, group_cols):
    """
    通用嵌套字典构建函数
    :param df: 输入的Pandas DataFrame
    :param target_col: 要提取列表的目标列名
    :param group_cols: 分组列列表,按从外到内的层级顺序排列
    :return: 嵌套字典
    """
    nested_dict = {}
    for keys, values in df.groupby(group_cols)[target_col]:
        current_level = nested_dict
        # 遍历除最后一个外的所有分组键,创建层级
        for key in keys[:-1]:
            if key not in current_level:
                current_level[key] = {}
            current_level = current_level[key]
        # 最后一个分组键对应目标列的唯一值列表
        current_level[keys[-1]] = values.unique().tolist()
    return nested_dict

# 调用函数快速生成结果
result = {
    'AREA_SUB_CODE_1': build_nested_dict(df, 'AREA_SUB_CODE_1', ['Region', 'Country', 'AREA_CODE']),
    'AREA_SUB_CODE_2': build_nested_dict(df, 'AREA_SUB_CODE_2', ['Region', 'Country', 'AREA_CODE', 'AREA_SUB_CODE_1'])
}

这样不管以后要加多少层分组,只要调整group_cols的列表就行,非常灵活~

备注:内容来源于stack exchange,提问作者SM079

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 18:13:10