DataFrame行转列:API分页pageSize=15时代码报错求助
问题分析与解决方案
为啥pageSize=15会报错?
大概率是这几个原因:
- 多数据量返回时,API的JSON结构和单条(pageSize=1)不一致,比如某个字段单条是字典,多条变成了列表,
json_normalize解析时直接出错 - 要
explode的字段里混了非列表类型(比如空值、单个字符串/数字),单条数据时没暴露问题,多条时就触发类型错误 pivot_table的聚合逻辑没明确,多数据行出现重复索引/列,默认聚合方式不兼容
一步步解决
1. 先确认API返回的结构差异
把pageSize=15时的API响应打印出来,和pageSize=1的对比,重点看你要拆解的核心字段:
import requests url = "你的API地址" params = {"pageSize": 15, "其他参数": "对应值"} resp = requests.get(url, params=params) print(resp.json()) # 直接查看目标字段是列表还是字典类型
2. 给json_normalize加明确参数,避免自动解析出错
不要依赖自动解析,手动指定record_path(要展开的嵌套列表路径)和meta(要保留的上层字段):
import pandas as pd # 示例:假设API有效数据在"data"下,明细在"data"内的"details"列表 df = pd.json_normalize( data["data"], record_path=["details"], # 指定要拆解的嵌套列表 meta=["id", "order_name"] # 保留这些上层关联字段 )
3. 先把要explode的字段统一成列表类型
不管是单个值还是空值,都转成列表,避免触发类型错误:
# 假设要拆解的字段叫"items" def safe_convert_to_list(x): if pd.isna(x): return [] return x if isinstance(x, list) else [x] df["items"] = df["items"].apply(safe_convert_to_list) df_exploded = df.explode("items", ignore_index=True)
4. pivot_table指定明确的聚合方式
多数据行必然会有重复的索引/列,得明确用什么聚合逻辑(比如取第一个值、求和):
df_pivoted = df_exploded.pivot_table( index=["id", "order_name"], columns="item_type", values="item_value", aggfunc="first", # 按需替换为sum/mean等 fill_value="" ).reset_index()
完整可复用代码
import requests import pandas as pd def process_api_data(page_size=15): # 1. 调用API并捕获请求错误 api_url = "https://你的API地址" params = {"pageSize": page_size, "pageNum": 1} resp = requests.get(api_url, params=params) resp.raise_for_status() # 遇到4xx/5xx错误直接抛出 raw_data = resp.json() # 2. 标准化嵌套JSON(根据你的API结构调整参数) df_normalized = pd.json_normalize( raw_data["records"], record_path=["details", "items"], meta=["id", "order_no", ["details", "total_amount"]], sep="_" # 嵌套字段用下划线拼接,避免列名冲突 ) # 3. 安全处理要explode的字段 df_normalized["sub_items"] = df_normalized["sub_items"].apply( lambda x: x if isinstance(x, list) else [] if pd.isna(x) else [x] ) df_exploded = df_normalized.explode("sub_items", ignore_index=True) # 4. 生成目标格式的透视表 df_pivoted = df_exploded.pivot_table( index=["id", "order_no"], columns="item_name", values="item_qty", aggfunc="sum", fill_value=0 ).reset_index() return df_pivoted # 测试运行 result_df = process_api_data(page_size=15) print(result_df.head())
额外排查技巧
- 看报错信息的具体内容:如果是
ValueError: cannot explode column of non-list type,用df["字段名"].apply(type).value_counts()统计字段类型分布,针对性处理 - 提前处理API返回的空值:部分API在pageSize较大时会返回
null,用df.fillna({"字段名": []})提前替换 - json_normalize加
errors="ignore":如果部分数据没有指定的record_path,不会直接报错,而是跳过
内容的提问来源于stack exchange,提问作者Jijju
相关产品推荐
相关产品推荐

