代码之家  ›  专栏  ›  技术社区  ›  Mr weasel

pandas:条件选择使用带有多索引的.loc

  •  3
  • Mr weasel  · 技术社区  · 6 年前

    我读过 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)
    

    这个数据帧是:

           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 回复  |  直到 6 年前
        1
  •  4
  •   rafaelc    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
    
        2
  •  4
  •   Mr weasel    5 年前

    我认为更简单的答案是使用 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
    
        3
  •  3
  •   ascripter    6 年前

    在索引列上的某些逻辑条件下,这可能是可能的 i0 i1 松开 .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])
    

    会屈服的

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

    注: slice(None) 意思与 [:] 在索引切片中。