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

如何通过Pandas extractall捕获组实现多匹配行的groupby分组?

解决Pandas中一行匹配多个分组时的groupby问题

当使用str.extract()处理包含多个匹配项的文本时,只能捕获第一个匹配结果,导致同时包含多个分组关键词的行仅被归入一个分组。而str.extractall()虽能捕获所有匹配,但返回的是带MultiIndex的二维DataFrame,直接传入groupby()会触发ValueError。以下是两种可行的解决方案:

方案一:合并DataFrame后分组

通过将原数据与extractall()的结果合并,让每个匹配项对应原数据的一行,再进行分组:

import pandas as pd
import re
from io import StringIO

DATA = StringIO('''
colA;colB;colC
Foo;1;1
Bar;2;2
Foo,Bar;3;3
''')
df = pd.read_csv(DATA, sep=';')

# 1. 提取所有匹配项并重置索引,保留原行号
matches = df['colA'].str.extractall('(Bar|Foo)', flags=re.IGNORECASE).reset_index()

# 2. 合并原DataFrame与匹配结果
merged_df = df.merge(matches, left_index=True, right_on='level_0')

# 3. 按匹配值分组
for group_name, group_data in merged_df.groupby(0):
    print(f"'{group_name}'")
    print(group_data[['colA', 'colB', 'colC']])
    print()

输出结果:

'Bar'
       colA  colB  colC
1      Bar     2     2
2  Foo,Bar     3     3

'Foo'
       colA  colB  colC
0      Foo     1     1
2  Foo,Bar     3     3

方案二:通过索引筛选直接分组

无需合并DataFrame,直接利用extractall()结果的MultiIndex提取原数据行:

import pandas as pd
import re
from io import StringIO

DATA = StringIO('''
colA;colB;colC
Foo;1;1
Bar;2;2
Foo,Bar;3;3
''')
df = pd.read_csv(DATA, sep=';')

# 提取所有匹配项
matches = df['colA'].str.extractall('(Bar|Foo)', flags=re.IGNORECASE)

# 遍历每个唯一匹配值,筛选对应行并分组
for group_name in matches[0].unique():
    # 获取匹配该值的所有原行索引
    row_ids = matches[matches[0] == group_name].index.get_level_values('level_0')
    # 提取对应分组数据
    group_data = df.loc[row_ids]
    print(f"'{group_name}'")
    print(group_data)
    print()

该方案输出与方案一完全一致,适合不需要保留匹配序号的场景。

关键说明

str.extractall()返回的DataFrame包含两级索引:level_0对应原数据的行索引,match对应同一行内的匹配序号。直接传入groupby()会因分组键是二维结构报错,因此需要通过重置索引或提取level_0来关联原数据,将分组键转换为一维结构。

内容的提问来源于stack exchange,提问作者PedroA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:45:31