如何处理pandas含列表项的列,将列表元素拆分为独立行?
问题说明
现有测试数据集,report_number列的部分单元格存储了多个报告编号组成的列表,测试数据构造代码:
import pandas as pd test = pd.DataFrame({ "report_number":[['21-10541', '21-6300'],['20-55506']], "date": ['2021-06-03','2021-06-04'] })
需要将每个单元格列表内的报告编号拆分为独立行,同时保留对应记录的date字段值,期望输出结构:
| report_number | date |
|---|---|
| 21-10541 | 2021-06-03 |
| 21-6300 | 2021-06-03 |
| 20-55506 | 2021-06-04 |
注:给出的期望输出里第一个编号
21-1054是笔误,和原始测试数据不匹配,实际输出会保留原始编号值。
之前尝试编写自定义函数,配合apply(axis=1)实现需求,代码如下:
def f(x): if len(x['report_number'])>1: for i in x['report_number']: return(i,x['date']) else: return (x['report_number'],x['date']) test.apply(f,axis=1)
这段代码运行后无法得到预期结果。
错误原因
这段代码的问题出在两个地方:
- 多编号分支的for循环第一次迭代就会触发
return,只会返回列表里的第一个报告编号,不会遍历完所有列表元素 apply(axis=1)的默认逻辑是每一行输入对应单条返回结果,本身不支持直接把单行拆成多行,靠普通return逻辑没法实现行展开效果。
正确实现方法
pandas自带专门用于拆分列表列为多行的explode()API,不需要写自定义循环,代码简洁且性能更好,实现代码:
# 指定要拆分的列,ignore_index=True重置拆分后的行索引 result = test.explode('report_number', ignore_index=True)
运行后得到的result就是符合需求的输出。
如果使用的pandas版本过低(0.25版本之前没有explode方法),可以通过遍历展开的方式实现:
temp = [] for _, row in test.iterrows(): for report_num in row['report_number']: temp.append({"report_number": report_num, "date": row["date"]}) result = pd.DataFrame(temp)
两种方式都能得到正确结果,优先推荐使用官方explode()方法。
内容的提问来源于stack exchange,提问作者Nathan123
相关产品推荐
相关产品推荐

