如何利用pandas的extractall()结果向原始数据集添加部分重复行?
Pandas处理:提取数字生成多行并保留空值行
需求说明
现有Pandas数据集,需完成以下操作:
- 对
name列非空的行,从b列提取所有数字 - 每个提取出的数字对应生成一行新数据,除
b列替换为提取的数字外,其他列与原行内容一致 - 保留原数据中
name列为空的行,最终得到目标数据集
示例数据
原始数据
import pandas as pd df = pd.DataFrame([{'name': 'Bob', 'a': '123', 'b': '111'}, {'name': None, 'a': '', 'b': '999'}, {'name': 'Alice', 'a': '234', 'b': '[555aaa, 666bbb]'}, {'name': 'Steve', 'a': '567', 'b': '[777ccc]'}])
输出:
| | name | a | b | |---:|:-------|:----|:-----------------| | 0 | Bob | 123 | 111 | | 1 | | | 999 | | 2 | Alice | 234 | [555aaa, 666bbb] | | 3 | Steve | 567 | [777ccc] |
提取结果(name非空行)
mask = df['name'].isna() m = df[~mask]['b'].str.extractall(r'([0-9]+)')
输出:
| | 0 | |:-------|----:| | (0, 0) | 111 | | (2, 0) | 555 | | (2, 1) | 666 | | (3, 0) | 777 |
期望最终结果
| | name | a | b | |---:|:-------|:----|:----| | 0 | Bob | 123 | 111 | | 1 | | | 999 | | 2 | Alice | 234 | 555 | | 2 | Alice | 234 | 666 | | 3 | Steve | 567 | 777 |
解决方案
直接赋值df[~mask]['b'] = ...无法得到正确结果,因为链式索引可能修改的是副本,且extractall返回的多级索引数据无法直接对应到原行。正确步骤如下:
- 拆分数据集:单独保留
name为空的行,避免后续处理影响这部分数据 - 提取并合并数据:对
name非空的行,提取数字后与原行(去掉原b列)合并,生成多行数据 - 合并最终结果:将处理后的非空行数据与保留的空行数据合并,按原索引排序
完整代码
import pandas as pd # 1. 生成原始数据 df = pd.DataFrame([{'name': 'Bob', 'a': '123', 'b': '111'}, {'name': None, 'a': '', 'b': '999'}, {'name': 'Alice', 'a': '234', 'b': '[555aaa, 666bbb]'}, {'name': 'Steve', 'a': '567', 'b': '[777ccc]'}]) # 2. 拆分出name为空的行 mask = df['name'].isna() df_null_name = df[mask] # 3. 处理name非空的行 df_non_null = df[~mask] # 提取b列中的数字,并重命名列为b extracted_nums = df_non_null['b'].str.extractall(r'(\d+)').rename(columns={0: 'b'}) # 合并原行(移除原b列)和提取的数字,生成多行 df_non_null_processed = df_non_null.drop('b', axis=1).join(extracted_nums) # 4. 合并两部分数据,按原索引排序 final_df = pd.concat([df_null_name, df_non_null_processed]).sort_index() # 输出结果 print(final_df.to_markdown())
代码说明
str.extractall(r'(\d+)'):提取所有连续数字,返回多级索引的DataFrame(原行索引+匹配序号)drop('b', axis=1).join(extracted_nums):移除原b列后,通过索引合并提取的数字,自动为每个数字生成对应行pd.concat(...):合并空行数据和处理后的非空行数据,sort_index()保证结果索引与原数据逻辑一致
内容的提问来源于stack exchange,提问作者banderlog013
相关产品推荐
相关产品推荐

