pandas:使用 .loc 和 MultiIndex 进行条件选择

Mr *_*sel 5 python multi-index dataframe pandas

我已经阅读了高级索引与分层索引的文档,其中解释了使用.locfor MultiIndex。还有这个线程:Using .loc with a MultiIndex in pandas?

我仍然没有看到如何选择行 (first index == some value) or (second index == some value)

例子:

import pandas as pd

index = pd.MultiIndex.from_arrays([['a', 'a', 'a', 'b', 'b', 'b'],
                                  ['a', 'b', 'c', 'a', 'b', 'c']],
                                  names=['i0', 'i1'])
df = pd.DataFrame({'x': [1,2,3,4,5,6], 'y': [6,5,4,3,2,1]}, index=index)
Run Code Online (Sandbox Code Playgroud)

这是数据帧:

       x  y
i0 i1      
a  a   1  6
   b   2  5
   c   3  4
b  a   4  3
   b   5  2
   c   6  1
Run Code Online (Sandbox Code Playgroud)

我怎样才能得到行在哪里i0 == 'b' or i1 == 'b'

       x  y
i0 i1      
a  b   2  5
b  a   4  3
   b   5  2
   c   6  1
Run Code Online (Sandbox Code Playgroud)

raf*_*elc 6

使用get_level_values()

>>> mask = (df.index.get_level_values(0)=='b') | (df.index.get_level_values(1)=='b') 
>>> df[mask]  # same as df.loc[mask]


        x   y
i0  i1      
a   b   2   5
b   a   4   3
    b   5   2
    c   6   1
Run Code Online (Sandbox Code Playgroud)


mma*_*123 6

我认为更简单的答案是使用DataFrame.query允许您按名称查询多索引的函数,如下所示:

import pandas as pd
import numpy as np

index = pd.MultiIndex.from_arrays([list("aaabbb"),
                                  list("abcabc")],
                                  names=['i0', 'i1'])
df = pd.DataFrame({'x': [1, 2, 3, 4, 5, 6], 'y': [6, 5, 4, 3, 2, 1]}, index=index)


df.query('i0 == "b" | i1 == "b"')
Run Code Online (Sandbox Code Playgroud)

返回:

       x  y
i0 i1      
a  b   2  5
b  a   4  3
   b   5  2
   c   6  1
Run Code Online (Sandbox Code Playgroud)


asc*_*ter 5

通过索引列i0i1unsing上的某些逻辑条件,这可能是可能的.loc。然而对我来说使用.iloc似乎更容易:

您可以iloc通过 获取索引pd.MultiIndex.get_locs

import pandas as pd
import numpy as np

index = pd.MultiIndex.from_arrays([list("aaabbb"),
                                  list("abcabc")],
                                  names=['i0', 'i1'])
df = pd.DataFrame({'x': [1, 2, 3, 4, 5, 6], 'y': [6, 5, 4, 3, 2, 1]}, index=index)

idx0 = index.get_locs(['b', slice(None)])  # i0 == 'b' => [3, 4, 5]
idx1 = index.get_locs([slice(None), 'b'])  # i1 == 'b' => [1, 4]
idx = np.union1d(idx0, idx1)

print(df.iloc[idx])
Run Code Online (Sandbox Code Playgroud)

将产生

       x  y
i0 i1      
a  b   2  5
b  a   4  3
   b   5  2
   c   6  1
Run Code Online (Sandbox Code Playgroud)

注意: 与索引切片中的slice(None)含义相同。[:]