如何基于MultiIndex单一层级筛选DataFrame子集?
优化MultiIndex层级筛选的实现方式
问题背景
现有带MultiIndex的DataFrame:
df = pd.DataFrame({"v":range(12)}, index=pd.MultiIndex.from_product([["a","b","c"],[1,2,3,4]]))
需求:筛选出第一层级为a或c的行,预期结果如下:
v a 1 0 2 1 3 2 4 3 c 1 8 2 9 3 10 4 11
当前实现代码会生成中间DataFrame,存在资源浪费:
df[df.index.to_frame()[0].isin(("a","c"))]
求更优的实现方式。
更优实现方式
方法1:利用get_level_values直接提取层级值
这是效率最高的方案之一,直接获取第一层级的索引值进行筛选,不会生成中间DataFrame:
df[df.index.get_level_values(0).isin(["a", "c"])]
如果给MultiIndex的层级指定了名称,也可以用名称替代索引位置,比如第一层级名为group:
df[df.index.get_level_values("group").isin(["a", "c"])]
方法2:结合xs与concat(适用于偏好xs语法的场景)
xs可以快速提取指定层级的单行,但默认仅支持单个值,若要筛选多个值,可通过pd.concat合并结果:
pd.concat([df.xs("a", level=0), df.xs("c", level=0)])
注:该方式在数据量较大时,效率略低于get_level_values,因需两次提取再合并。
方法3:使用query实现简洁筛选
先给MultiIndex的层级命名:
df.index.names = ["level1", "level2"]
之后即可通过query语法实现可读性更强的筛选:
df.query("level1 in ['a', 'c']")
内容的提问来源于stack exchange,提问作者sds
相关产品推荐
相关产品推荐

