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

如何将含字典与列表的DataFrame列展开为目标结构?

问题与解决方案

问题描述

现有如下结构的初始DataFrame:

| Category | idlist                                                           |
| -------- | -----------------------------------------------------------------|
| new      | {100: ['1A', '2B'], 200: ['2A', '3B'], 300: ['3A', '3B', '4B']}  |
| old      |  ['99A', '99B']                                                  |

需要将其转换为以下目标结构:

| Category | id  | list                 |
| -------- | --- | -------------------- |
| new      | 100 | ['1A', '2B']         |     
| new      | 200 | ['2A', '3B']         |
| new      | 300 | ['3A', '3B', '4B']   |
| old      | -1  | ['99A', '99B']       |

其中new类别的idlist是数字为键、列表为值的字典;old类别仅为列表,无对应id,默认设为-1。同时需要统一处理两类数据,转换前的原始JSON格式如下:

{'new' : {100: ['1-A', '2-B'], 200: ['2-A', '3-B'], 300: ['3-A', '3-B', '4-B']}, 'old' :  ['99-A', '99-B']}

解决方案

可以通过两种方式实现转换,均能统一处理字典和列表类型的数据:

方法一:直接从原始JSON构建目标DataFrame

遍历原始JSON的键值对,区分字典和列表类型,分别生成对应数据行后拼接成最终DataFrame。

import pandas as pd

raw_json = {'new' : {100: ['1-A', '2-B'], 200: ['2-A', '3-B'], 300: ['3-A', '3-B', '4-B']}, 'old' :  ['99-A', '99-B']}

data_rows = []
for category, content in raw_json.items():
    if isinstance(content, dict):
        # 处理字典类型:遍历键值对生成多行
        for id_num, item_list in content.items():
            data_rows.append({
                'Category': category,
                'id': id_num,
                'list': item_list
            })
    elif isinstance(content, list):
        # 处理列表类型:添加默认id-1
        data_rows.append({
            'Category': category,
            'id': -1,
            'list': content
        })

# 转换为目标DataFrame
result_df = pd.DataFrame(data_rows)
print(result_df)

运行输出:

Category   id                     list
0      new  100              ['1-A', '2-B']
1      new  200              ['2-A', '3-B']
2      new  300  ['3-A', '3-B', '4-B']
3      old  -1              ['99-A', '99-B']

方法二:从已有初始DataFrame转换

针对已存在的初始DataFrame,使用apply逐行处理生成展开记录,再合并为新DataFrame。

import pandas as pd

# 构造初始DataFrame
initial_df = pd.DataFrame({
    'Category': ['new', 'old'],
    'idlist': [
        {100: ['1A', '2B'], 200: ['2A', '3B'], 300: ['3A', '3B', '4B']},
        ['99A', '99B']
    ]
})

# 定义行处理函数
def expand_row(row):
    category = row['Category']
    content = row['idlist']
    output_rows = []
    if isinstance(content, dict):
        for id_num, item_list in content.items():
            output_rows.append({
                'Category': category,
                'id': id_num,
                'list': item_list
            })
    elif isinstance(content, list):
        output_rows.append({
            'Category': category,
            'id': -1,
            'list': content
        })
    return pd.DataFrame(output_rows)

# 应用函数并合并结果
result_df = pd.concat(initial_df.apply(expand_row, axis=1).tolist(), ignore_index=True)
print(result_df)

运行输出:

Category   id                     list
0      new  100              ['1A', '2B']
1      new  200              ['2A', '3B']
2      new  300  ['3A', '3B', '4B']
3      old  -1              ['99A', '99B']

核心说明

  • 通过isinstance()判断idlist的类型,精准区分字典和列表进行差异化处理;
  • 字典类型直接遍历键值对生成多行记录,数字键可直接作为id列的值,不存在格式问题;
  • 列表类型生成单条记录,统一设置默认id为-1,实现两类数据的统一转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:25:18