【问题标题】:Accessing one level of a multi-index in Pandas在 Pandas 中访问一级多索引
【发布时间】:2019-05-22 23:23:02
【问题描述】:

我有一个看起来像是多索引的简单用例的数据框:我有 ISO 周数和日期作为索引,我想按特定周过滤。按照the docs 中的说明,看起来我应该能够通过传递周数字符串来建立索引。但是,这给我传递了一个关键错误。

MCVE:

data = {'foo': {('2016_32', '2016-08-07'): 0.14285714285714285,
  ('2016_32', '2016-08-08'): 0.14285714285714285,
  ('2016_32', '2016-08-09'): 0.14285714285714285,
  ('2016_32', '2016-08-10'): 0.14285714285714285,
  ('2016_32', '2016-08-11'): 0.14285714285714285,
  ('2016_32', '2016-08-12'): 0.14285714285714285,
  ('2016_32', '2016-08-13'): 0.14285714285714285,
  ('2016_36', '2016-09-04'): 0.14285714285714285,
  ('2016_36', '2016-09-05'): 0.14285714285714285,
  ('2016_36', '2016-09-06'): 0.14285714285714285,
  ('2016_36', '2016-09-07'): 0.14285714285714285,
  ('2016_36', '2016-09-08'): 0.14285714285714285,
  ('2016_36', '2016-09-09'): 0.14285714285714285},
 'bar': {('2016_32', '2016-08-07'): np.nan,
  ('2016_32', '2016-08-08'): np.nan,
  ('2016_32', '2016-08-09'): np.nan,
  ('2016_32', '2016-08-10'): np.nan,
  ('2016_32', '2016-08-11'): np.nan,
  ('2016_32', '2016-08-12'): np.nan,
  ('2016_32', '2016-08-13'): np.nan,
  ('2016_36', '2016-09-04'): 0.0,
  ('2016_36', '2016-09-05'): 0.0,
  ('2016_36', '2016-09-06'): 0.0,
  ('2016_36', '2016-09-07'): 0.0,
  ('2016_36', '2016-09-08'): 0.0,
  ('2016_36', '2016-09-09'): 0.0}}

df = pd.DataFrame(data)
df['2016_32']

KeyError: '2016_32'

【问题讨论】:

    标签: python pandas multi-index


    【解决方案1】:

    一般选择Multiindex使用DataFrame.xs

    #default first level should be omit
    print (df.xs('2016_32'))
    #select by second level
    #print (df.xs('2016-09-07', level=1))
                     foo  bar
    2016-08-07  0.142857  NaN
    2016-08-08  0.142857  NaN
    2016-08-09  0.142857  NaN
    2016-08-10  0.142857  NaN
    2016-08-11  0.142857  NaN
    2016-08-12  0.142857  NaN
    2016-08-13  0.142857  NaN
    

    loc:

    #no parameter if select first level
    print (df.loc['2016_32'])
    #if want select second level axis=0 and : for select all values of first level
    print (df.loc(axis=0)[:, '2016-09-07'])
    

    MultiIndex 在列和行中的选择差异:

    np.random.seed(235)
    a = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']),
              np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])]
    a1 = pd.MultiIndex.from_product([['A', 'B', 'C'], ['E','F']])
    df = pd.DataFrame(np.random.randint(10, size=(6, 8)), index=a1, columns=a)
    print (df)
        bar     baz     foo     qux    
        one two one two one two one two
    A E   8   1   5   8   3   5   3   3
      F   3   1   3   6   6   1   0   2
    B E   0   3   1   7   0   0   8   2
      F   6   7   7   4   2   7   7   5
    C E   7   3   1   7   3   9   7   3
      F   8   2   0   8   5   2   2   0
    

    #select by column bar level  
    print (df['bar'])
         one  two
    A E    8    1
      F    3    1
    B E    0    3
      F    6    7
    C E    7    3
      F    8    2
    
    #select by column bar and then by `one`
    print (df['bar']['one'])
    A  E    8
       F    3
    B  E    0
       F    6
    C  E    7
       F    8
    Name: one, dtype: int32
    
    #select by tuples for columns select
    print (df[('bar', 'one')])
    A  E    8
       F    3
    B  E    0
       F    6
    C  E    7
       F    8
    Name: (bar, one), dtype: int32
    

    对于按行选择(索引中的MultiIndex)使用loc

    print (df.loc['A'])
      bar     baz     foo     qux    
      one two one two one two one two
    E   8   1   5   8   3   5   3   3
    F   3   1   3   6   6   1   0   2
    
    print (df.loc['A'].loc['F'])
    bar  one    3
         two    1
    baz  one    3
         two    6
    foo  one    6
         two    1
    qux  one    0
         two    2
    Name: F, dtype: int32
    
    print (df.loc[('A', 'F')])
    bar  one    3
         two    1
    baz  one    3
         two    6
    foo  one    6
         two    1
    qux  one    0
         two    2
    Name: (A, F), dtype: int32
    

    【讨论】:

    • 谢谢,这确实有效!您能否解释一下这与文档中的 this example 有何不同?
    • @JoshFriedlander - 我认为df['col'] 在列中选择第一级MultiIndex 是有区别的,在您的示例中是index 中的MulitIndex,所以需要loc
    • df.xs 是一个横截面方法,DataFrame 的 xs() 方法额外采用了一个 level 参数,以便更容易地选择 MultiIndex 特定级别的数据。
    • @jezrael,不错!
    • 知道了。在文档中,示例术语 bar 既是列名又是级别名,因此我感到困惑
    【解决方案2】:

    或者,您可以在不更改顺序的情况下使用与swaplevel 交换级别:

    >>> df[:7].swaplevel(0, 0, axis=0)
                             foo  bar
    2016_32 2016-08-07  0.142857  NaN
            2016-08-08  0.142857  NaN
            2016-08-09  0.142857  NaN
            2016-08-10  0.142857  NaN
            2016-08-11  0.142857  NaN
            2016-08-12  0.142857  NaN
            2016-08-13  0.142857  NaN
    

    或者简单地说:

    >>> df[1:7]
                             foo  bar
    2016_32 2016-08-08  0.142857  NaN
            2016-08-09  0.142857  NaN
            2016-08-10  0.142857  NaN
            2016-08-11  0.142857  NaN
            2016-08-12  0.142857  NaN
            2016-08-13  0.142857  NaN
    

    【讨论】:

      猜你喜欢
      • 2021-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-20
      • 2019-10-27
      • 2018-03-13
      • 2013-11-09
      • 2015-11-04
      相关资源
      最近更新 更多