请考虑具有多索引的Pandas数据帧:
df = pd.DataFrame({'x': [1, 2, 3, 4]})
arrays = [[1, 1, 2, 2], [False, True, False, True]]
df.index = pd.MultiIndex.from_arrays(arrays, names=('grp', 'is_even'))
df
x
grp is_even
1 False 1
True 2
2 False 3
True 4
我可以 Select 一个特定的条目-比方说,grp == 1 & is_even == True
:
df.loc[(1, True)]
x 2
Name: (1, True), dtype: int64
使用slice
或pd.IndexSlice
表示法,我可以为first索引级别(grp == 1
) Select 一个特定值,以及第二个级别的所有值:
# with slice()
df.loc[slice(1), slice(None)]
x
grp is_even
1 False 1
True 2
# with pd.IndexSlice
idx = pd.IndexSlice
df.loc[idx[1, :]] # note - correct rows selected but grp index level not shown
x
is_even
False 1
True 2
但是,当我try Select 第一个索引级别的all values和第二个索引级别的特定值(例如is_even == True
)时,此语法模式失败(第二个索引级别的值上的KeyError).
df.loc[idx[:, True]] # also throws KeyError with df.loc[(slice(None), slice(True))]
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
~/anaconda3/envs/betterup-example-analysis/lib/python3.6/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
2645 try:
-> 2646 return self._engine.get_loc(key)
2647 except KeyError:
# ...
错误跟踪很长(如果查看全部内容有帮助的话,还可以用这段代码重现),但其中一段有几条注释提示问题所在(粗体):
~/anaconda3/envs/betterup-example-analysis/lib/python3.6/site-packages/pandas/core/indexing.py in _getitem_lowerdim(self, tup)
1371 # we may have a nested tuples indexer here
1372 if self._is_nested_tuple_indexer(tup):
-> 1373 return self._getitem_nested_tuple(tup)
1374
1375 # we maybe be using a tuple to represent multiple dimensions here
经过一些试验后,我发现添加一个列占位符可以解决这个错误.(这样做还可以恢复上面IndexSlice
个示例中缺失的第一个索引级别.)
df.loc[idx[:, True], :]
x
grp is_even
1 True 2
2 True 4
我还发现我可以用query
分到达那里:
df.query('is_even == True')
所以我很高兴我有了一个解决方案,但是我的Pandas-Fu还不够强大,不能理解why如果不包括列占位符,错误就会发生.如果有人能帮我弄清楚这里发生了什么,我将不胜感激!
Pandas version: 1.0.5
Python version: 3.6.15