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

如何从Python嵌套字典列表提取指定键高效生成DataFrame?

高效解析嵌套字典生成DataFrame的方法

问题背景

我有如下嵌套结构的字典:

from decimal import Decimal

data_dict = {'Company': [
                    {
                        'Date': [{'L_End': {'@value': '2013-03-31'},
                                 'L_Start': {'@value': '2006-10-01'},
                                 'Type': {'@value': 'L'}},
                                {'O_Start': {'@value': '2006-10-01'},
                                 'Type': {'@value': 'O'}}],
                       'GeoLoc': {'Location': {'AddrLn1': 'HIGHLAND ROAD',
                                               'Country': 'ENGLAND',
                                               'County': 'HAMPSHIRE',
                                               'PostCode': 'PO49HU',
                                               'Town': 'SOUTHSEA',
                                               'UPRN': Decimal('1775')}},
                       'Name': 'Courtney',
                       'OrgId': {'@assigningAuthorityName': 'ABCDE',
                                 '@extension': 'a12cde',
                                 '@root': '2.16.840.1.1'},
                       'Status': {'@value': 'Active'},
                   },
                  {
                       'Date': [{'L_End': {'@value': '2013-03-31'},
                                 'L_Start': {'@value': '2006-10-01'},
                                 'Type': {'@value': 'L'}},
                                {'O_Start': {'@value': '2006-10-01'},
                                 'Type': {'@value': 'O'}}],
                       'GeoLoc': {'Location': {'AddrLn1': 'VILLIERS ROAD',
                                               'Country': 'ENGLAND',
                                               'County': 'HAMPSHIRE',
                                               'PostCode': 'PO52HG',
                                               'Town': 'SOUTHSEA'}},
                       'Name': 'MERLIN',
                       'OrgId': {'@assigningAuthorityName': 'ABCDE',
                                 '@extension': 'b12cde',
                                 '@root': '2.16.840.1.1'},
                       'Status': {'@value': 'Active'}
                   }
                  ]
}

需要将其转换为指定结构的DataFrame,目前的实现需要多次拆分、拼接列,步骤繁琐:

import pandas as pd

df = pd.DataFrame.from_dict(data_dict)
df1 = pd.DataFrame(df.Company.values.tolist())

df2 = pd.concat([df1, df1.OrgId.apply(lambda x: pd.Series(x))], axis=1)
df2 = df2.drop(['OrgId', '@root', '@assigningAuthorityName'], axis=1)
df2 = df2.rename(columns={"@extension": "OrgId"})

df3 = pd.concat([df2, df2.Date.apply(lambda x: pd.Series(x))], axis=1)
df3 = df3.drop('Date', axis=1)

df4 = pd.concat([df3, df3[0].apply(lambda x: pd.Series(x))], axis=1)
df4 = df4.drop([0, 'Type'], axis=1)
# ...后续重复类似操作直到提取所有所需列

df11 = pd.concat([df10, df10.Location.apply(lambda x: pd.Series(x))], axis=1)
df11 = df11.drop('Location', axis=1)

final_df = df11.copy()
print(final_df)

高效实现方案

方法一:利用pd.json_normalize快速展开+列整理

pd.json_normalize是Pandas专门用于处理嵌套JSON/字典的工具,能直接生成带层级分隔的列,再配合简单的列处理即可得到目标结构:

import pandas as pd
from decimal import Decimal

# 1. 直接展开Company列表生成初始DataFrame
df = pd.json_normalize(data_dict['Company'])

# 2. 处理Date列的嵌套列表,提取所有日期字段
def flatten_date(date_list):
    date_info = {}
    for item in date_list:
        # 跳过Type字段,提取其他日期字段的@value值
        for key, val in item.items():
            if key != 'Type':
                date_info[key] = val['@value']
    return pd.Series(date_info)

date_df = df['Date'].apply(flatten_date)

# 3. 合并所需列并整理命名
final_df = pd.concat([
    # 保留基础字段
    df[['Name']],
    # 提取OrgId的有效字段并重命名
    df['OrgId.@extension'].rename('OrgId'),
    # 提取Status字段
    df['Status.@value'].rename('Status'),
    # 合并处理后的日期字段
    date_df,
    # 提取地址字段并去掉前缀
    df.filter(like='GeoLoc.Location.').rename(columns=lambda x: x.replace('GeoLoc.Location.', ''))
], axis=1)

print(final_df)

方法二:预处理字典扁平化后再生成DataFrame

先递归处理嵌套字典,提取所有@value并合并Date列表,再用pd.json_normalize直接生成扁平DataFrame,代码更简洁:

import pandas as pd
from decimal import Decimal

def preprocess_item(item):
    # 递归提取@value字段,简化嵌套层级
    def extract_value(obj):
        if isinstance(obj, dict):
            if '@value' in obj:
                return obj['@value']
            return {k: extract_value(v) for k, v in obj.items()}
        elif isinstance(obj, list):
            return [extract_value(i) for i in obj]
        return obj
    
    processed = extract_value(item)
    
    # 合并Date列表中的多个字典为单个字典
    if 'Date' in processed:
        date_combined = {}
        for date_item in processed['Date']:
            # 移除Type字段,合并日期字段
            date_item.pop('Type')
            date_combined.update(date_item)
        processed['Date'] = date_combined
    
    return processed

# 预处理所有Company条目
processed_companies = [preprocess_item(comp) for comp in data_dict['Company']]

# 直接生成扁平DataFrame
final_df = pd.json_normalize(processed_companies)

# 按需调整列顺序(可选)
final_df = final_df[['Name', 'OrgId', 'Status', 'L_Start', 'L_End', 'O_Start',
                     'AddrLn1', 'Town', 'County', 'PostCode', 'Country', 'UPRN']]

print(final_df)

两种方法都能避免多次拆分拼接的繁琐操作,方法二更适合结构复杂或后续可能变化的场景,扩展性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 17:45:49