explode()是pandas 0.25+展开list列的原生方法,保持原始索引(重复出现),不支持多列同时展开,需链式调用;默认将None展开为NaN行,空值处理需谨慎;性能上易致内存飙升,索引重复后不再唯一。

用 explode() 展开 list 列并保留原始索引
explode() 是 pandas 0.25+ 提供的原生方法,专为展开嵌套 list(或 tuple、Series)列设计,天然保持原始行索引。只要目标列每个元素是可迭代对象(如 [1, 2]、["a", "b"]),调用后每项会“摊平”成独立行,原索引重复出现。
关键点:它不是“重置索引”,而是“复制索引”——原 df.index 不变,只是某些索引值出现多次。
- 若原 DataFrame 索引是整数且连续(如
RangeIndex(0, 3)),结果中会出现重复数字,比如0, 0, 1, 2, 2, 2 - 若原索引是自定义标签(如
["A", "B", "C"]),结果中对应标签也会重复,比如"A", "A", "B", "C", "C" - 不支持直接对多列同时
explode();需链式调用或循环处理
处理含空值(None 或 NaN)的 list 列
explode() 默认将 None 或 pd.NA 展开为单个 NaN 行(即该行其他列照常,被展开列为 NaN)。如果想跳过这些空行,得先过滤或用 dropna() 清洗。
- 默认行为:
df.explode("col")遇到None→ 输出一行,该列值为NaN - 跳过空值:
df.explode("col").dropna(subset=["col"]),但注意这会丢弃整行(其他列也跟着被删) - 更安全做法:先用
df.loc[df["col"].apply(lambda x: isinstance(x, (list, tuple)) and len(x) > 0)]过滤再 explode
一次展开多列 list 的正确写法
explode() 不接受列表参数,不能写成 df.explode(["col1", "col2"])。必须逐列调用,且要注意顺序——后展开的列会基于前一次 explode 的结果继续拆分,可能产生笛卡尔式膨胀。
- 错误示例:
df.explode(["A", "B"])→ 报错TypeError: explode() takes 2 positional arguments but 3 were given - 正确串行展开(按需):
df.explode("A").explode("B"),前提是两列都含 list,且语义上允许组合爆炸 - 若只想分别展开、不交叉,应先
reset_index(),对每列单独explode()后再按原索引合并,但通常没必要——多数场景只需单列展开
性能与内存注意事项
当 list 很长或行数很多时,explode() 会显著增加行数,可能引发内存飙升甚至 OOM。它内部是拷贝数据,不是视图。
- 提前估算膨胀比:
df["col"].str.len().sum() / len(df)可粗略看平均膨胀倍数 - 避免在大表上对未过滤列直接
explode();先用.loc限定子集 - 若后续要 groupby 原索引统计,记得用
groupby(level=0)(针对重复索引)或groupby("original_index_col")(若已保存原索引)
真正容易被忽略的是索引语义变化:展开后索引不再是唯一标识符,所有依赖 df.loc[idx] 精确定位的操作都可能返回多行——这点在 join、赋值或调试时极易出错。










