如何使用布尔类型的多索引访问 Pandas 数据帧中的行 ( "IndexError: Item wrong length 2 instead of 3." )



考虑一个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就无法判断两者中的哪一个。通过使用元组,可以清楚地表明所提供的值实际上是一个标签,而不是计算某个条件的结果。

最新更新