Pandas多索引DataFrame:筛选值大于同主索引subcat1行的记录
解决多级索引DataFrame的条件筛选问题
这问题我熟,咱们一步步来搞定它——要筛选出每行value大于同一级索引(index0)下二级索引为subcat1的对应值的行,其实可以通过提取参考值+条件比较来实现,下面是具体步骤:
1. 先创建可复现的示例DataFrame
首先咱们把你给出的数据转换成可运行的代码,方便后续测试:
import pandas as pd # 构建数据和多级索引 data = { 'name': ['henk', 'klaas', 'jan', 'piet', 'joris', 'corneel'], 'value': [6, 7, 10, 7, 8, 9] } multi_index = pd.MultiIndex.from_tuples( [('cat1', 'subcat1'), ('cat2', 'subcat1'), ('cat3', 'subcat1'), ('cat1', 'subcat2'), ('cat2', 'subcat2'), ('cat3', 'subcat2')], names=['index0', 'index1'] ) df = pd.DataFrame(data, index=multi_index)
2. 方法一:提取参考值后映射比较
这种方式逻辑清晰,容易理解:
- 先提取所有二级索引为
subcat1的行,得到每个index0对应的参考value - 把参考值映射到原DataFrame的每一行,生成辅助列
- 基于辅助列做条件筛选,最后去掉辅助列
代码实现:
# 提取每个index0下subcat1对应的参考value ref_values = df.xs('subcat1', level='index1')['value'] # 将参考值映射到原DataFrame的每一行 df['ref_value'] = df.index.get_level_values('index0').map(ref_values) # 筛选满足条件的行,并移除辅助列 filtered_df = df[df['value'] > df['ref_value']].drop(columns='ref_value')
3. 方法二:用groupby+transform简化操作
如果想更简洁,可以直接用groupby按index0分组,然后通过transform把每组的参考值广播到所有行,直接做比较:
filtered_df = df[df['value'] > df.groupby(level='index0')['value'].transform( lambda group: group[group.index.get_level_values('index1') == 'subcat1'].iloc[0] )]
最终结果
两种方法得到的结果一致,都是:
name value index0 index1 cat1 subcat2 piet 7 cat2 subcat2 joris 8
内容的提问来源于stack exchange,提问作者mottie91
相关产品推荐
相关产品推荐

