熊猫:使用带有MultiIndex的.loc进行条件选择

时间:2018-06-25 23:25:22

标签: python pandas dataframe multi-index

我已阅读Advanced indexing with hierarchical index的文档,其中说明了将.loc用于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)

这是DataFrame:

       x  y
i0 i1      
a  a   1  6
   b   2  5
   c   3  4
b  a   4  3
   b   5  2
   c   6  1

如何获取i0 == 'b' or i1 == 'b'处的行?

       x  y
i0 i1      
a  b   2  5
b  a   4  3
   b   5  2
   c   6  1

3 个答案:

答案 0 :(得分:4)

使用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

答案 1 :(得分:4)

我认为更简单的答案是使用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"')

返回:

       x  y
i0 i1      
a  b   2  5
b  a   4  3
   b   5  2
   c   6  1

答案 2 :(得分:3)

在索引列i0i1上未加上.loc的逻辑条件下,可能会发生这种情况。但是对我来说,使用.iloc似乎更容易:

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

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])

会产生

       x  y
i0 i1      
a  b   2  5
b  a   4  3
   b   5  2
   c   6  1

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