我有一个MultiIndex数据框,我试图根据我的列中的值范围和最外层的索引级别来索引。因此,使用下面的示例,例如我正在尝试从v2
中选择l2
所在的v1 > 12
我可以使用多个索引语句来实现这一点,例如:
df[df.v1>12].loc['l2', 'v2']
,但这似乎不太理想。有没有办法将其压缩成单个语句?
我一直在试图弄清楚如何使用pd.IndexSlice
,但似乎无法理解文档的MultiIndex部分中的示例正在做什么。
df = pd.concat([pd.DataFrame({'v1': range(10, 15), 'v2':range(5, 0, -1)})
for i in range(2)], keys=['l1', 'l2'])
v1 v2
l1 0 10 5
1 11 4
2 12 3
3 13 2
4 14 1
l2 0 10 5
1 11 4
2 12 3
3 13 2
4 14 1
答案 0 :(得分:1)
您可以使用slicers选择,然后使用loc
修改boolean indexing
以选择列v2
:
idx = pd.IndexSlice
df1 = df.loc[idx['l2', :], :]
print (df1)
v1 v2
l2 0 10 5
1 11 4
2 12 3
3 13 2
4 14 1
print (df1.loc[df1.v1 > 12, 'v2'])
l2 3 2
4 1
Name: v2, dtype: int32
xs
的另一个解决方案:
df1 = df.xs('l2')
print (df1)
v1 v2
0 10 5
1 11 4
2 12 3
3 13 2
4 14 1
print (df1.loc[df1.v1 > 12, 'v2'])
3 2
4 1
Name: v2, dtype: int32
df1 = df.xs('l2', drop_level=False)
print (df1)
v1 v2
l2 0 10 5
1 11 4
2 12 3
3 13 2
4 14 1
print (df1.loc[df1.v1 > 12, 'v2'])
l2 3 2
4 1
Name: v2, dtype: int32
通过get_level_values
选择第一级索引的解决方案,如果需要删除第一级使用droplevel
或reset_index
,则为last:
df1 = df.loc[(df.v1 > 12) & (df.index.get_level_values(0) == 'l2'), 'v2']
df1.index = df1.index.droplevel(0)
#df1 = df1.reset_index(level=0, drop=True)
print (df1)
3 2
4 1
Name: v2, dtype: int32
IndexSlice
的示例:
从1
到3
选择第一级和第二级的所有值(感谢 piRSquared ):
idx = pd.IndexSlice
print (df.loc[idx[:, 1:3], :])
v1 v2
l1 1 11 4
2 12 3
3 13 2
l2 1 11 4
2 12 3
3 13 2