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

如何高效将含JSON对象字符串列表的Pandas Series转为DataFrame

高效转换JSON字符串列表的Pandas Series为目标DataFrame

嘿,我懂你这种想用更优雅方法替代嵌套循环的心情!作为Pandas新手,确实很容易先想到手动遍历,但其实Pandas有一堆内置工具能帮我们高效搞定这个转换,完全不用写多层循环~

下面是一步步的简洁实现方案,我们来拆解整个过程:

1. 先导入必要的库

import pandas as pd
import json

2. 定义你的原始Series

sr = pd.Series(['[{"fruit": "apple", "box_a": 2}, {"fruit": "grape", "box_b": 4}]',
               '[{"fruit": "orange", "box_g": 2}]',
               '[{"fruit": "mango", "box_c": 6}, {"fruit": "grape", "box_e": 3}]'])

3. 解析JSON字符串为Python列表

首先,我们需要把每个字符串格式的JSON列表转换成Python的字典列表,用json.loads()配合apply()就能批量完成:

sr_parsed = sr.apply(json.loads)

4. 展开列表为单独的字典行

现在每个元素是一个包含1-2个字典的列表,我们用explode()把列表拆成单独的行,这样每行就对应一个字典:

sr_exploded = sr_parsed.explode()

5. 提取目标字段并整理成DataFrame

这里有两种简洁的方式:

方法一:用自定义函数处理每个字典

因为每个字典里只有fruit和一个box_xxx键值对,我们可以写个小函数提取这三个字段:

def extract_fruit_box_count(d):
    fruit = d['fruit']
    # 取出除了fruit之外的唯一键值对
    box_name, count = next((k, v) for k, v in d.items() if k != 'fruit')
    return pd.Series([fruit, box_name, count], index=['fruit', 'box', 'count'])

# 应用函数并重置索引
df_final = sr_exploded.apply(extract_fruit_box_count).reset_index(drop=True)

方法二:用melt重塑表格

如果你的数据可能有多个box字段(虽然这里没有),用melt会更通用:

# 先把字典转成宽格式DataFrame
wide_df = sr_exploded.apply(pd.Series)
# 找出所有box开头的列
box_columns = [col for col in wide_df.columns if col.startswith('box_')]
# 把宽格式转成长格式
df_final = wide_df.melt(
    id_vars='fruit',
    value_vars=box_columns,
    var_name='box',
    value_name='count'
).dropna().reset_index(drop=True)

最终结果

运行完上面的代码后,df_final就是你想要的结构:

fruit    box  count
0   apple  box_a      2
1   grape  box_b      4
2  orange  box_g      2
3   mango  box_c      6
4   grape  box_e      3

为什么这比嵌套循环好?

Pandas的这些内置方法(apply、explode、melt)底层都是优化过的C代码实现,比纯Python的嵌套循环快得多,尤其是当你的数据量很大的时候,效率差距会非常明显。而且代码更简洁易读,后续维护也更方便~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:06:38