Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 选择多索引数据框中的行_Python_Pandas_Dataframe_Slice_Multi Index - Fatal编程技术网

Python 选择多索引数据框中的行

Python 选择多索引数据框中的行,python,pandas,dataframe,slice,multi-index,Python,Pandas,Dataframe,Slice,Multi Index,选择/筛选行的最常用方法是什么? 基于单个值/标签的切片 基于一个或多个级别的多个标签进行切片 布尔条件和表达式的过滤 哪些方法适用于什么情况 为简单起见,假设: 输入数据帧没有重复的索引键 下面的输入数据帧只有两个级别。(此处显示的大多数解决方案可推广到N个级别) 输入示例: 问题1:选择单个项目 如何选择级别“1”中具有“a”的行 此外,我如何才能在输出中降低级别“1” col two t 0 u 1 v 2 w 3

选择/筛选行的最常用方法是什么?

  • 基于单个值/标签的切片
  • 基于一个或多个级别的多个标签进行切片
  • 布尔条件和表达式的过滤
  • 哪些方法适用于什么情况
为简单起见,假设:

  • 输入数据帧没有重复的索引键
  • 下面的输入数据帧只有两个级别。(此处显示的大多数解决方案可推广到N个级别)

  • 输入示例: 问题1:选择单个项目 如何选择级别“1”中具有“a”的行

    此外,我如何才能在输出中降低级别“1”

         col
    two     
    t      0
    u      1
    v      2
    w      3
    
         col
    two     
    t      0
    u      1
    v      2
    w      3
    
    问题1b
    如何在级别“2”上对值为“t”的所有行进行切片

    问题2:在一个级别中选择多个值 如何选择级别“一”中项目“b”和“d”对应的行

    问题2b
    如何获得级别“2”中与“t”和“w”对应的所有值

    问题3:切片单个横截面
    (x,y)
    如何从
    df
    检索横截面,即具有特定索引值的单行?具体来说,如何检索
    ('c','u')
    的横截面,由

             col
    one two     
    c   u      9
    
             col
    one two     
    c   u      9
    
    问题4:切片多个横截面
    [(a,b),(c,d),…]
    如何选择与
    ('c','u')
    ('a','w')
    相对应的两行

    问题5:每级切片一个项目 如何检索与级别“1”中的“a”或级别“2”中的“t”对应的所有行

    问题6:任意切片 如何切片特定的横截面?对于“a”和“b”,我想选择所有子级别为“u”和“v”的行,对于“d”,我想选择子级别为“w”的行

    问题7将使用由数字级别组成的唯一设置:

    np.random.seed(0)
    mux2 = pd.MultiIndex.from_arrays([
        list('aaaabbbbbccddddd'),
        np.random.choice(10, size=16)
    ], names=['one', 'two'])
    
    df2 = pd.DataFrame({'col': np.arange(len(mux2))}, mux2)
    
             col
    one two     
    a   5      0
        0      1
        3      2
        3      3
    b   7      4
        9      5
        3      6
        5      7
        2      8
    c   4      9
        7     10
    d   6     11
        8     12
        8     13
        1     14
        6     15
    
    问题7:在多指标的各个层次上通过数值不等式进行过滤 如何获取级别“2”中的值大于5的所有行

             col
    one two     
    b   7      4
        9      5
    c   7     10
    d   6     11
        8     12
        8     13
        6     15
    
             col
    one two     
    b   7      4
        9      5
    c   7     10
    d   6     11
        8     12
        8     13
        6     15
    

    注意:这篇文章将不讨论如何创建多索引,如何对它们执行赋值操作,或者任何与性能相关的讨论(这些是另一次单独讨论的主题)

    注意
    该员额的结构将如下:

  • OP中提出的问题将逐一解决
  • 对于每个问题,将演示一种或多种适用于解决此问题并获得预期结果的方法
  • 注意s(与此类似)将提供给有兴趣了解其他功能、实施细节、, 以及其他与当前主题相关的信息。这些便笺已经过修改 通过对文件的梳理和对各种模糊信息的揭露 功能,并从我自己(承认有限)的经验

    所有代码示例都已在pandas v0.23.4和python3.7上创建和测试。如果有些事情不清楚,或者事实上不正确,或者如果你没有 找到适用于您的用例的解决方案,请随时 建议编辑,在评论中要求澄清,或打开新的 问题……如适用

    下面是我们将经常重温的一些常见习语(以下简称四习语)的介绍

  • -标签选择的通用解决方案(+适用于涉及切片的更复杂应用)

  • -从系列/数据帧中提取特定横截面

  • -动态指定切片和/或筛选操作(即,作为动态计算的表达式)。与其他情况相比,它更适用于某些情况。另请参阅有关查询多索引的信息

  • 使用生成掩码的布尔索引(通常与一起使用,尤其是在使用多个值进行筛选时)。在某些情况下,这也非常有用

  • 从这四种习惯用法的角度来看各种切片和过滤问题将有助于更好地理解什么可以应用于给定的情况。了解并非所有习惯用法都同样有效(如果有的话)是非常重要的在任何情况下。如果一个习语没有被列为下面某个问题的潜在解决方案,这意味着该习语不能有效地应用于该问题


    问题1 如何选择级别“1”中具有“a”的行

    您可以使用
    loc
    ,作为适用于大多数情况的通用解决方案:

    df.loc[['a']]
    
    在这一点上,如果你

    TypeError: Expected tuple, got str
    

    这意味着你在使用一个较老版本的大熊猫。考虑升级,否则,使用<代码> df.LOC[ [(a,'切片(无)]:] /<代码>

    或者,您可以在此处使用
    xs
    ,因为我们提取的是单个横截面。请注意
    级别
    参数(此处可以假设合理的默认值)

    在这里,需要使用
    drop_level=False
    参数来防止
    xs
    在结果中删除级别“1”(我们切片的级别)

    这里的另一个选项是使用
    query

    df.query("one == 'a'")
    
    items = ['b', 'd']
    df.query("one in @items")
    # df.query("one == @items", parser='pandas')
    # df.query("one in ['b', 'd']")
    # df.query("one == ['b', 'd']", parser='pandas')
    
    如果索引没有名称,则需要将查询字符串更改为
    “ilevel_0=='a'”

    最后,使用
    获取级别值

    df[df.index.get_level_values('one') == 'a']
    # If your levels are unnamed, or if you need to select by position (not label),
    # df[df.index.get_level_values(0) == 'a']
    
    此外,我如何才能在输出中降低级别“1”

         col
    two     
    t      0
    u      1
    v      2
    w      3
    
         col
    two     
    t      0
    u      1
    v      2
    w      3
    
    这可以通过以下两种方法轻松实现:

    df.loc['a'] # Notice the single string argument instead the list.
    
    或者

    请注意,我们可以省略
    drop\u level
    参数(默认情况下,它假定为
    True

    注意
    您可能会注意到,经过筛选的数据帧可能仍然具有所有级别,即使在打印数据帧时没有显示这些级别。例如

    v = df.loc[['a']]
    print(v)
             col
    one two     
    a   t      0
        u      1
        v      2
        w      3
    
    print(v.index)
    MultiIndex(levels=[['a', 'b', 'c', 'd'], ['t', 'u', 'v', 'w']],
               labels=[[0, 0, 0, 0], [0, 1, 2, 3]],
               names=['one', 'two'])
    
    您可以使用以下方法消除这些级别:


    问题1b 如何在级别上对值为“t”的所有行进行切片
    df.query("one == 'a'")
    
    df[df.index.get_level_values('one') == 'a']
    # If your levels are unnamed, or if you need to select by position (not label),
    # df[df.index.get_level_values(0) == 'a']
    
         col
    two     
    t      0
    u      1
    v      2
    w      3
    
    df.loc['a'] # Notice the single string argument instead the list.
    
    df.xs('a', level=0, axis=0, drop_level=True)
    # df.xs('a')
    
    v = df.loc[['a']]
    print(v)
             col
    one two     
    a   t      0
        u      1
        v      2
        w      3
    
    print(v.index)
    MultiIndex(levels=[['a', 'b', 'c', 'd'], ['t', 'u', 'v', 'w']],
               labels=[[0, 0, 0, 0], [0, 1, 2, 3]],
               names=['one', 'two'])
    
    v.index = v.index.remove_unused_levels()
    
    print(v.index)
    MultiIndex(levels=[['a'], ['t', 'u', 'v', 'w']],
               labels=[[0, 0, 0, 0], [0, 1, 2, 3]],
               names=['one', 'two'])
    
             col
    one two     
    a   t      0
    b   t      4
        t      8
    d   t     12
    
    df.loc[(slice(None), 't'), :]
    
    idx = pd.IndexSlice
    df.loc[idx[:, 't'], :]
    
    df.loc(axis=0)[pd.IndexSlice[:, 't']]
    
    df.xs('t', axis=0, level=1, drop_level=False)
    
    df.query("two == 't'")
    # Or, if the first level has no name, 
    # df.query("ilevel_1 == 't'") 
    
    df[df.index.get_level_values('two') == 't']
    # Or, to perform selection by position/integer,
    # df[df.index.get_level_values(1) == 't']
    
             col
    one two     
    b   t      4
        u      5
        v      6
        w      7
        t      8
    d   w     11
        t     12
        u     13
        v     14
        w     15
    
    df.loc[['b', 'd']]
    
    items = ['b', 'd']
    df.query("one in @items")
    # df.query("one == @items", parser='pandas')
    # df.query("one in ['b', 'd']")
    # df.query("one == ['b', 'd']", parser='pandas')
    
    df[df.index.get_level_values("one").isin(['b', 'd'])]
    
             col
    one two     
    a   t      0
        w      3
    b   t      4
        w      7
        t      8
    d   w     11
        t     12
        w     15
    
    df.loc[pd.IndexSlice[:, ['t', 'w']], :] 
    
    items = ['t', 'w']
    df.query("two in @items")
    # df.query("two == @items", parser='pandas') 
    # df.query("two in ['t', 'w']")
    # df.query("two == ['t', 'w']", parser='pandas')
    
    df[df.index.get_level_values('two').isin(['t', 'w'])]
    
             col
    one two     
    c   u      9
    
    df.loc[('c', 'u'), :]
    
    df.loc[pd.IndexSlice[('c', 'u')]]
    
    PerformanceWarning: indexing past lexsort depth may impact performance.
    
    df_sort = df.sort_index()
    df_sort.loc[('c', 'u')]
    
    df.xs(('c', 'u'))
    
    df.query("one == 'c' and two == 'u'")
    
    m1 = (df.index.get_level_values('one') == 'c')
    m2 = (df.index.get_level_values('two') == 'u')
    df[m1 & m2]
    
             col
    one two     
    c   u      9
    a   w      3
    
    df.loc[[('c', 'u'), ('a', 'w')]]
    # df.loc[pd.IndexSlice[[('c', 'u'), ('a', 'w')]]]
    
    cses = [('c', 'u'), ('a', 'w')]
    levels = ['one', 'two']
    # This is a useful check to make in advance.
    assert all(len(levels) == len(cs) for cs in cses) 
    
    query = '(' + ') or ('.join([
        ' and '.join([f"({l} == {repr(c)})" for l, c in zip(levels, cs)]) 
        for cs in cses
    ]) + ')'
    
    print(query)
    # ((one == 'c') and (two == 'u')) or ((one == 'a') and (two == 'w'))
    
    df.query(query)
    
    df[df.index.droplevel(unused_level).isin([('c', 'u'), ('a', 'w')])]
    
             col
    one two     
    a   t      0
        u      1
        v      2
        w      3
    b   t      4
        t      8
    d   t     12
    
    pd.concat([
        df.loc[['a'],:], df.loc[pd.IndexSlice[:, 't'],:]
    ])
    
             col
    one two     
    a   t      0
        u      1
        v      2
        w      3
        t      0   # Does this look right to you? No, it isn't!
    b   t      4
        t      8
    d   t     12
    
    v = pd.concat([
            df.loc[['a'],:], df.loc[pd.IndexSlice[:, 't'],:]
    ])
    v[~v.index.duplicated()]
    
    df.query("one == 'a' or two == 't'")
    
    m1 = (df.index.get_level_values('one') == 'a')
    m2 = (df.index.get_level_values('two') == 't')
    df[m1 | m2] 
    
             col
    one two     
    a   u      1
        v      2
    b   u      5
        v      6
    d   w     11
        w     15
    
    keys = [('a', 'u'), ('a', 'v'), ('b', 'u'), ('b', 'v'), ('d', 'w')]
    df.loc[keys, :]
    
    pd.concat([
         df.loc[(('a', 'b'), ('u', 'v')), :], 
         df.loc[('d', 'w'), :]
       ], axis=0)
    
             col
    one two     
    b   7      4
        9      5
    c   7     10
    d   6     11
        8     12
        8     13
        6     15
    
    df2.query("two > 5")
    
    df2[df2.index.get_level_values('two') > 5]
    
    np.random.seed(0)
    mux3 = pd.MultiIndex.from_product([
            list('ABCD'), list('efgh')
    ], names=['one','two'])
    
    df3 = pd.DataFrame(np.random.choice(10, (3, len(mux))), columns=mux3)
    print(df3)
    
    one  A           B           C           D         
    two  e  f  g  h  e  f  g  h  e  f  g  h  e  f  g  h
    0    5  0  3  3  7  9  3  5  2  4  7  6  8  8  1  6
    1    7  7  8  1  5  9  8  9  4  3  0  3  5  0  2  3
    2    8  1  3  3  3  7  0  1  9  9  0  4  7  3  2  7
    
     df3.loc[:, ....] # Notice how we slice across the index with `:`. 
    
     df3.loc[:, pd.IndexSlice[...]]
    
     df.loc[:, {condition}] 
    
     df3.T.query(...).T
    
        index = pd.MultiIndex.from_product([['a','b'],
                                   ['stock1','stock2','stock3'],
                                   ['price','volume','velocity']])
    
        df = pd.DataFrame([1,2,3,4,5,6,7,8,9,
                          10,11,12,13,14,15,16,17,18], 
                           index)
    
                            0
        a stock1 price      1
                 volume     2
                 velocity   3
          stock2 price      4
                 volume     5
                 velocity   6
          stock3 price      7
                 volume     8
                 velocity   9
        b stock1 price     10
                 volume    11
                 velocity  12
          stock2 price     13
                 volume    14
                 velocity  15
          stock3 price     16
                 volume    17
                 velocity  18
    
        df.xs(('stock1', 'velocity'), level=(1,2))
    
            0
        a   3
        b  12
    
       df.iloc[df.index.isin(['stock1'], level=1) & 
               df.index.isin(['velocity'], level=2)] 
    
                            0
        a stock1 velocity   3
        b stock1 velocity  12
    
        df.iloc[df.index.isin(['stock1','stock3'], level=1) & 
                df.index.isin(['velocity'], level=2)] 
    
                            0
        a stock1 velocity   3
          stock3 velocity   9
        b stock1 velocity  12
          stock3 velocity  18
    
    df.sql(<SQL select statement>)