如何使用字典过滤多层索引的Pandas DataFrame?
动态过滤多层索引DataFrame的实现方案
构造示例DataFrame
首先构造包含多层索引的示例DataFrame:
import pandas as pd mi = pd.MultiIndex( levels = [[1, 2, 3], ['red', 'green', 'blue'], ['a', 'b', 'c']], codes = [[1,0,1,0], [0,1,1,2], [1,0,0,1]], names = ["Key1", "Key2", "Key3"]) df = pd.DataFrame({ "values": [1, 2, 3, 4] }, index = mi)
该DataFrame的结构如下:
values Key1 Key2 Key3 2 red b 1 1 green a 2 2 green a 3 1 blue b 4
已知的手动过滤方式
可以通过手动构造索引层级的过滤条件实现筛选,示例代码如下:
df[ df.index.get_level_values("Key1").isin([1]) & df.index.get_level_values("Key2").isin(["green"]) ]
需求说明
需要编写通用函数,通过传入类似{"Key1":1, "Key2":"green"}的字典实现过滤,要求:
- 不能硬编码过滤的层级数量
- 支持传入单个条件(如
{"Key1":1}或{"Key2":"green"})
解决方案
方法一:循环构建过滤掩码
通过遍历条件字典,逐步构建过滤掩码,逻辑清晰易理解:
def filter_multi_index(df, conditions): # 初始化全True的掩码 mask = pd.Series([True] * len(df), index=df.index) for level, value in conditions.items(): # 处理单个值的情况,统一转为列表 if not isinstance(value, (list, tuple)): value = [value] # 叠加当前层级的过滤条件 mask &= df.index.get_level_values(level).isin(value) return df[mask]
方法二:用reduce组合谓词
借助functools.reduce和逻辑运算符,实现更简洁的条件组合:
from functools import reduce import operator def filter_multi_index(df, conditions): predicates = [] for level, value in conditions.items(): # 统一处理单个值和多值的情况 val_list = value if isinstance(value, (list, tuple)) else [value] predicates.append(df.index.get_level_values(level).isin(val_list)) # 用逻辑与组合所有条件 mask = reduce(operator.and_, predicates) return df[mask]
测试示例
- 多条件筛选:
filter_multi_index(df, {"Key1":1, "Key2":"green"})
输出结果:
values Key1 Key2 Key3 1 green a 2
- 单个条件筛选:
filter_multi_index(df, {"Key1":2})
输出结果:
values Key1 Key2 Key3 2 red b 1 2 green a 3
内容的提问来源于stack exchange,提问作者butterflyknife
相关产品推荐
相关产品推荐

