pandas对列表列执行explode操作时新增枚举列的Pythonic实现方案
问题描述
现有如下初始DataFrame:
>>> df = pd.DataFrame({'A': [1,2,3], 'B':['abc', 'def', 'ghi']}).apply({'A':int, 'B':list}) >>> df A B 0 1 [a, b, c] 1 2 [d, e, f] 2 3 [g, h, i]
需求是将B列的列表拆分为多行,同时新增两列:B1存列表元素的下标,B2存对应的元素值,最终得到如下结果:
A B1 B2 0 1 0 a 1 1 1 b 2 1 2 c 3 2 0 d 4 2 1 e 5 2 2 f 6 3 0 g 7 3 1 h 8 3 2 i
原实现方式步骤冗余且存在语法错误,有没有更简洁优雅的Pythonic写法?
最优实现方案
推荐以下写法,逻辑清晰且性能更优:
import pandas as pd # 构造初始数据 df = pd.DataFrame({'A': [1,2,3], 'B':['abc', 'def', 'ghi']}).apply({'A':int, 'B':list}) # 核心逻辑 df = df.explode('B', ignore_index=True) df.insert(1, 'B1', df.groupby('A').cumcount()) df.rename(columns={'B': 'B2'}, inplace=True)
如果偏好链式写法,可调整为:
df = ( df.explode('B', ignore_index=True) .assign(B1=lambda x: x.groupby('A').cumcount()) .rename(columns={'B': 'B2'}) .loc[:, ['A', 'B1', 'B2']] )
方案说明
- 先用pandas原生的
explode方法直接把B列的列表炸开,每个元素单独占一行,比自定义apply的性能高很多 - 用
groupby('A').cumcount()直接生成每个元素在原列表内的下标,天然匹配B1列的需求,不需要额外处理枚举值 - 最后仅需调整列名和顺序即可,全程无冗余操作,可读性极强
内容的提问来源于stack exchange,提问作者rudolfovic
相关产品推荐
相关产品推荐

