You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用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返回的多级索引数据无法直接对应到原行。正确步骤如下:

  1. 拆分数据集:单独保留name为空的行,避免后续处理影响这部分数据
  2. 提取并合并数据:对name非空的行,提取数字后与原行(去掉原b列)合并,生成多行数据
  3. 合并最终结果:将处理后的非空行数据与保留的空行数据合并,按原索引排序

完整代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 14:52:51