pd.json_normalize()不总适用,因其仅处理字典/json-like结构,对纯列表嵌套会报错;深层嵌套需递归展平,单层可用explode(),混合结构应先类型检查再选方案。

嵌套列表直接传给 pd.DataFrame() 会报错或产生意外的列类型,必须先展平再构造 DataFrame。
为什么 pd.json_normalize() 不总适用?
它专为字典/JSON-like 结构设计,对纯列表嵌套(如 [[1,2], [3,[4,5]], [6]])无能为力——遇到非字典元素直接跳过或报 AttributeError: 'list' object has no attribute 'items'。
- 仅当嵌套结构中每层都是
dict(含键值对)时,pd.json_normalize()才可靠 - 若数据混有 list、None、标量,需先统一转成 dict 或改用递归展平
- 深层嵌套(>3 层)时,
record_path参数易配错,调试成本高
手动递归展平:用函数处理任意深度列表
写一个轻量递归函数,比依赖外部库更可控,也避免 itertools.chain.from_iterable() 只支持单层展开的限制。
def flatten_nested(lst):
result = []
for item in lst:
if isinstance(item, list):
result.extend(flatten_nested(item))
else:
result.append(item)
return result
<h1>示例</h1><p>data = [[1, 2], [3, [4, 5]], [6, [7, [8, 9]]]]
print(flatten_nested(data)) # [1, 2, 3, 4, 5, 6, 7, 8, 9]</p>
- 该函数不修改原数据,返回新列表,适合管道式处理
- 若需保留层级信息(如标记来源索引),得改造成带路径追踪的版本
- 遇到
None或字符串时,要加isinstance(item, (str, bytes))判断,否则字符串会被误拆成字符
用 pd.DataFrame.explode() 处理“半展平”场景
当嵌套只有一层(如每行是 list,但 list 内部不再嵌套),explode() 是最简洁、性能最好的方案,且天然支持多列同步爆炸。
df = pd.DataFrame({'id': [1, 2], 'values': [[10, 20], [30, 40, 50]]})
df_exploded = df.explode('values').reset_index(drop=True)
# id values
# 0 1 10
# 1 1 20
# 2 2 30
# 3 2 40
# 4 2 50
-
explode()要求目标列是 list/tuple/None,不能是 string 或 scalar - 若列中混有
None,默认保留为一行NaN;加参数ignore_index=False可保持原始索引 - 多个嵌套列需分别调用
explode(),顺序影响结果(建议先explode('col_a'),再explode('col_b'))
真正麻烦的是混合结构:既有字典又有列表,还有缺失值。这时候别硬套一个函数,先用 type() 和 isinstance() 检查几条样本,再决定走 json_normalize、explode 还是自定义递归——临时补丁往往比通用方案更稳。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











