考虑这个带有 MultiIndex 的 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
我可以选择一个特定条目 - 例如,
grp == 1 & is_even == True
:
df.loc[(1, True)]
x 2
Name: (1, True), dtype: int64
并且使用
slice
或 pd.IndexSlice
表示法,我可以为 first 索引级别 (grp == 1
) 选择特定值,以及第二级别的所有值:
# 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
但是当我尝试选择第一个索引级别的所有值以及第二个索引级别的特定值(例如
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 在 _getitem_lowerdim(self, tup)
第1371章 第1372章 - > 1373返回self._getitem_nested_tuple(tup) 1374 第1375章
经过一些实验,我发现添加列占位符可以解决该错误。 (这样做还会恢复上面IndexSlice
示例中缺失的第一个索引级别。)df.loc[idx[:, True], :] x grp is_even 1 True 2 2 True 4
query
到达那里:
df.query('is_even == True')
所以我很高兴我有一个修复程序,但我的 Pandas-fu 还不够强大,无法理解为什么
在不包含列占位符的情况下会发生错误。如果有人可以帮助我了解这里发生的事情,我将非常感激!熊猫版本:1.0.5
Python版本:3.6.15
idx[:, True]
实际上只是一个要创建的包装器:
(slice(None, None, None), True)
通过执行
df.loc[idx[:, True], :]
,您明确表示列切片器是 :
进一步的演示是尝试运行
df.loc[idx[:, 'x']]
,这将正确地对列进行切片
x
。