如何合理将Zendesk API返回的字典列表转换为pandas DataFrame
Zendesk API工单数据结构化转换方案
问题说明
Zendesk API返回的工单数据为字典列表格式,单个字典对应一条工单记录。对于字典嵌套字典的常规结构,直接调用json_normalize即可快速完成结构化处理,但返回数据中custom_fields字段为存储id与value映射的字典列表,且存在特殊约束:并非所有工单记录都包含相同的自定义字段ID。
示例数据结构如下:
data = [{ "ticket_id": 4, "customer_id": 8, "created_at": "2022-05-01", "custom_fields": [ {"id": 15, "value": "website"}, {"id": 16, "value": "broken"}, {"id": 23, "value": None} ], 'group_id': 42 }]
直接使用DataFrame构造函数、from_records、from_json或json_normalize加载数据时,仅能将外层字段转为独立列,custom_fields列表会整体作为单列存储,无法实现嵌套字段的结构化拆分:
t_df = pd.json_normalize(data) t_df
原有逐行处理方案通过逐行提取custom_fields转置后与原表合并,可以得到预期宽表(custom_fields中的id转为独立列名,对应value作为列值,与外层基础字段合并),但处理25000条量级的记录时,存在运行效率低、鲁棒性差易报错的问题。
原有实现代码如下:
t_df = pd.DataFrame(sample_df.at[0, 'custom_fields']).T.reset_index(drop=True) t_df.rename(columns=t_df.iloc[0], inplace=True) t_df.drop(0, inplace=True) t_df.reset_index(drop=True, inplace=True) pd.merge(left=sample_df, left_index=True, right=t_df, right_index=True).drop(columns='custom_fields')
高效稳定实现方案
基于列表推导+pandas原生向量化操作实现,无逐行循环的冗余开销,自动适配不同工单自定义字段不一致的场景,完整代码如下:
import pandas as pd # 1. 加载外层基础字段,暂存custom_fields列后续处理 base_df = pd.json_normalize(data) # 2. 批量将每条工单的custom_fields转为{字段id:字段值}的映射字典 custom_field_map = [ {field["id"]: field["value"] for field in per_ticket_fields} for per_ticket_fields in base_df["custom_fields"] ] # 3. 直接将映射字典列表转为DataFrame,自动对齐所有出现过的自定义字段为列,缺失值自动填充 custom_df = pd.DataFrame(custom_field_map) # 4. 横向拼接基础字段与自定义字段,删除原嵌套的custom_fields列得到最终宽表 result_df = pd.concat( [base_df.drop(columns="custom_fields"), custom_df], axis=1 )
方案优势
- 处理效率高:全程无逐行DataFrame构造、转置、重命名操作,列表推导+C底层实现的concat拼接,25000条记录可在百毫秒级完成处理,效率比原逐行方案高两个数量级
- 鲁棒性强:无需提前预知所有自定义字段ID,自动识别全量数据中出现过的字段生成列,单条工单缺失对应字段时自动填充空值,不会因字段不匹配触发报错
- 维护成本低:逻辑链路简洁,无冗余的索引重置、删行、关联操作,后续新增字段处理规则时调整成本极低
内容的提问来源于stack exchange,提问作者DChaps
相关产品推荐
相关产品推荐

