pandas:具有多索引的布尔索引

Kor*_*rem 8 python pandas

这里有很多类似标题的问题,但我找不到解决这个问题的问题.

我有来自许多不同来源的数据帧,我想逐个过滤.当布尔序列与过滤的数据帧大小相同时,使用布尔索引很有效,但是当序列的大小与过滤的数据帧的更高级索引相同时,则不能.

简而言之,假设我有这个数据帧:

In [4]: df = pd.DataFrame({'a':[1,1,1,2,2,2,3,3,3], 
                           'b':[1,2,3,1,2,3,1,2,3], 
                           'c':range(9)}).set_index(['a', 'b'])
Out[4]: 
     c
a b   
1 1  0
  2  1
  3  2
2 1  3
  2  4
  3  5
3 1  6
  2  7
  3  8
Run Code Online (Sandbox Code Playgroud)

而这个系列:

In [5]: filt = pd.Series({1:True, 2:False, 3:True})
Out[6]: 
1     True
2    False
3     True
dtype: bool
Run Code Online (Sandbox Code Playgroud)

我想要的输出是这样的:

     c
a b   
1 1  0
  2  1
  3  2
3 1  6
  2  7
  3  8
Run Code Online (Sandbox Code Playgroud)

我不是在寻找不使用该filt系列的解决方案,例如:

df[df.index.get_level_values('a') != 2]
df[df.index.get_level_values('a').isin([1,3])]
Run Code Online (Sandbox Code Playgroud)

我想知道我是否可以filt按原样使用输入系列,因为我会在c上使用过滤器:

filt = df.c < 7
df[filt]
Run Code Online (Sandbox Code Playgroud)

Ema*_*ini 6

如果将索引 'a' 转换回列,则可以按如下方式进行:

>>> df = pd.DataFrame({'a':[1,1,1,2,2,2,3,3,3], 
                       'b':[1,2,3,1,2,3,1,2,3], 
                       'c':range(9)})
>>> filt = pd.Series({1:True, 2:False, 3:True})
>>> df[filt[df['a']].values]
   a  b  c
0  1  1  0
1  1  2  1
2  1  3  2
6  3  1  6
7  3  2  7
8  3  3  8
Run Code Online (Sandbox Code Playgroud)

编辑。正如@joris 所建议的,这也适用于索引。这是您的示例数据的代码:

>>> df[filt[df.index.get_level_values('a')].values]
     c
a b   
1 1  0
  2  1
  3  2
3 1  6
  2  7
  3  8
Run Code Online (Sandbox Code Playgroud)

  • @Korem它确实像您发布的那样工作,您只是忘记了答案中的“.values”。 (2认同)