如何用Python将嵌套字典列表转换为指定结构的DataFrame?
问题描述
我有如下嵌套字典列表:
ip_purchase = [ { 'V_TYPE': 'Purchase', 'V_No': '1', 'DATE': '20230401', 'ITEMS': [{'NAME': 'A100', 'AMOUNT': '-10000.00'}] }, { 'V_TYPE': 'Purchase', 'V_No': '2', 'DATE': '20230401', 'ITEMS': [{'NAME': 'RTX A6000', 'AMOUNT': '-50000.00'}, {'NAME': 'Jetson Nano', 'AMOUNT': '-4000.00'}, {'NAME': 'V100', 'AMOUNT': '-45000.00'}] }, { 'V_TYPE': 'Purchase', 'V_No': '3', 'DATE': '20230401', 'ITEMS': [{'NAME': 'A100', 'AMOUNT': '-10000.00'}, {'NAME': 'V100', 'AMOUNT': '-45000.00'}] }, ]
需要将其转换为如下结构的DataFrame:
| V_TYPE | V_No | DATE | ITEMS | AMOUNT |
|---|---|---|---|---|
| Purchase | 1 | 20230401 | A100 | -10000 |
| Purchase | 2 | 20230401 | RTX A6000 | -50000 |
| Purchase | 2 | 20230401 | Jetson Nano | -4000 |
| Purchase | 2 | 20230401 | V100 | -45000 |
| Purchase | 3 | 20230401 | A100 | -10000 |
| Purchase | 3 | 20230401 | V100 | -45000 |
直接用pd.DataFrame(ip_purchase)会因为ITEMS的嵌套列表导致格式混乱,且需要支持任意数量的外层订单和内层条目。
解决方案
以下三种方法都能实现需求,可根据习惯选择:
方法1:列表推导式预处理数据
手动遍历展开嵌套结构,逻辑直观易懂:
import pandas as pd # 展开嵌套数据 flattened_data = [] for order in ip_purchase: # 提取订单基础信息(排除ITEMS) base_info = {k: v for k, v in order.items() if k != 'ITEMS'} # 遍历每个条目,拼接成新行 for item in order['ITEMS']: flattened_row = { **base_info, 'ITEMS': item['NAME'], 'AMOUNT': int(float(item['AMOUNT'])) } flattened_data.append(flattened_row) # 生成DataFrame df = pd.DataFrame(flattened_data) print(df)
方法2:pandas explode + apply
利用pandas内置方法展开嵌套列,再提取字段:
import pandas as pd # 先转成基础DataFrame df = pd.DataFrame(ip_purchase) # 展开ITEMS列的嵌套列表 df_exploded = df.explode('ITEMS', ignore_index=True) # 从ITEMS字典中拆分出NAME和AMOUNT df_exploded[['ITEMS', 'AMOUNT']] = df_exploded['ITEMS'].apply(pd.Series) # 转换金额类型并调整列顺序 df_exploded['AMOUNT'] = df_exploded['AMOUNT'].astype(float).astype(int) df_exploded = df_exploded[['V_TYPE', 'V_No', 'DATE', 'ITEMS', 'AMOUNT']] print(df_exploded)
方法3:json_normalize直接解析嵌套结构
用pandas的json_normalize直接处理嵌套结构,一步到位:
import pandas as pd # 解析嵌套数据,指定记录路径和元数据字段 df = pd.json_normalize( ip_purchase, record_path='ITEMS', # 要展开的嵌套列表字段 meta=['V_TYPE', 'V_No', 'DATE'] # 保留的上层字段 ) # 重命名列并调整顺序 df = df.rename(columns={'NAME': 'ITEMS'})[['V_TYPE', 'V_No', 'DATE', 'ITEMS', 'AMOUNT']] # 转换金额类型 df['AMOUNT'] = df['AMOUNT'].astype(float).astype(int) print(df)
内容的提问来源于stack exchange,提问作者spectre
相关产品推荐
相关产品推荐

