如何在子索引满足条件时选取完整的MultiIndex数据
问题描述
构建了如下MultiIndex结构的DataFrame:
import numpy as np import pandas as pd arrays = [ np.array(["bar", "bar", "baz", "baz", "foo", "foo", "qux", "qux"]), np.array(["one", "two", "one", "two", "one", "two", "one", "two"])] df = pd.DataFrame(np.random.randn(8, 4), index=arrays)
对应的输出示例:
0 1 2 3 bar one -0.424972 0.567020 0.276232 -1.087401 two -0.673690 0.113648 -1.478427 0.524988 baz one 0.404705 0.577046 1.715002 -1.039268 two -0.370647 -1.157892 1.344312 0.844885 foo one 1.075770 -0.109050 1.643563 -1.469388 two 0.357021 -0.674600 -1.776904 -0.968914 qux one -1.294524 0.413738 0.276662 -0.472035 two -0.013960 -0.362543 -0.006154 -0.923061
需求:筛选出子索引(level=1)为"two"的行中,第2列(列索引为2)值小于0的所有完整分组(即对应一级索引的所有行,包含"one"和"two"子索引),期望结果如下:
0 1 2 3 bar one -0.424972 0.567020 0.276232 -1.087401 two -0.673690 0.113648 -1.478427 0.524988 foo one 1.075770 -0.109050 1.643563 -1.469388 two 0.357021 -0.674600 -1.776904 -0.968914 qux one -1.294524 0.413738 0.276662 -0.472035 two -0.013960 -0.362543 -0.006154 -0.923061
解决方案
步骤1:定位符合条件的一级索引
先筛选出子索引为"two"且第2列值小于0的行,提取对应的一级索引:
# 获取符合条件的一级索引列表 valid_groups = df.loc[(slice(None), "two"), 2][lambda x: x < 0].index.get_level_values(0)
步骤2:提取完整分组数据
用得到的一级索引从原DataFrame中提取所有对应分组的行:
result = df.loc[valid_groups]
合并写法
可以把两步合并成一行代码:
result = df.loc[df.loc[(slice(None), "two"), 2].lt(0).index.get_level_values(0)]
代码解释
df.loc[(slice(None), "two"), 2]:选取所有一级索引下,子索引为"two"的行的第2列数据.lt(0):等价于<0,判断这些值是否小于0,返回布尔型Series.index.get_level_values(0):从符合条件的行索引中提取一级索引(如bar、foo、qux)df.loc[valid_groups]:根据一级索引提取对应分组的所有行,包含该一级索引下的所有子索引行
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

