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

如何基于前两层索引组合筛选Pandas多层索引DataFrame?

问题

我有一个带多层索引的Pandas DataFrame,筛选后得到了除最后一层外的多组索引组合(即sel),示例代码如下:

import pandas as pd

df = pd.DataFrame({'a': ['A', 'B', 'A', 'B'], 'b': ['X', 'X', 'X', 'Y'],
                   'c': ['S', 'T', 'T', 'T'], 'd': [1, 2, 3, 1]}).set_index(['a', 'b', 'c'])

print(df.to_string())
# 输出:
#        d
# a b c
# A X S  1
# B X T  2
# A X T  3
# B Y T  1

sel = df.index.droplevel('c')[df.d == 1]  # 基于多层索引的筛选逻辑
print(sel)
# 输出:
# MultiIndex([('A', 'X'),
#             ('B', 'Y')],
#            names=['a', 'b'])

现在想获取原DataFrame中所有(a,b)属于sel的行(也就是除第二行外的所有行),试过.loc、.xs都没成功,不想用修改索引或内连接这类临时方案,有没有更直接的方法?

解决方案

这里有几个直接的方法,不用修改原索引也不用内连接:

方法1:直接用.loc索引(最简洁)

Pandas支持用层级更少的MultiIndex去索引多层索引的DataFrame,它会自动匹配对应层级的所有子行:

result = df.loc[sel]
print(result.to_string())
# 输出:
#        d
# a b c
# A X S  1
#   X T  3
# B Y T  1

这就是你要的结果,直接传sel给.loc就会匹配前两层a和b,返回所有对应c的行。

方法2:用index.isin指定层级判断

如果需要更明确地指定匹配的层级,可以用index.isin,并通过level参数指定要匹配的索引名:

# 把sel转成元组列表,然后判断原索引的a、b层级是否匹配
mask = df.index.isin(list(sel), level=['a', 'b'])
result = df[mask]

方法3:临时提取索引列判断

也可以临时提取前两层索引列,转成元组后判断是否在sel中:

# 重置索引提取a、b列,转成元组后匹配sel
mask = df.reset_index()[['a', 'b']].apply(tuple, axis=1).isin(sel)
result = df[mask]

内容的提问来源于stack exchange,提问作者Michel de Ruiter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 05:20:24