考虑一个Pandas DataFrame,它具有所有布尔类型级别的MultiIndex(下面的示例(。试图使用布尔标签访问此类DataFrame的特定行会导致错误:
df = pd.DataFrame([[False, False, 1],
[False, True, 2],
[True, False, 3]], columns=["A", "B", "C"])
df.set_index(["A", "B"], inplace=True)
print( df.loc[[False, False]] ) # IndexError: Item wrong length 2 instead of 3.
如何使用布尔类型的MultiIndex访问DataFrame中的行?
您可以使用pd.IndexSlice
进行切片。
>>> df.loc[pd.IndexSlice[False, False]]
C 1
Name: (False, False), dtype: int64
使用元组访问行。
print( df.loc[(False, False)] )
如果只有列表形式的值,请在访问之前将它们转换为元组。
x = [False, False] # possibly result of some previous computation
print( df.loc[tuple(x)] )
背景
通常,使用如下值列表可以很容易地访问具有多索引的Pandas DataFrame中的行:
df = pd.DataFrame([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]], columns=["A", "B", "C"])
df.set_index(["A", "B"], inplace=True)
print( df.loc[[1, 2]] ) # prints first row of the DataFrame
在这个例子中,唯一与问题不同的是MultiIndex的数据类型。对MultiIndex使用布尔数据类型的问题在于它与布尔索引冲突。
布尔索引允许根据某些条件选择行。例如,我们可以使用df.loc[df["C"] < 7]
选择C列中值小于7的所有行。内部条件导致布尔值数组,因此这与df.loc[[True, True, False]]
相同。
这显然与MultiIndex相冲突——如果同时支持使用列表的MultiIndex访问和布尔索引,Panda就无法判断两者中的哪一个。通过使用元组,可以清楚地表明所提供的值实际上是一个标签,而不是计算某个条件的结果。