【问题标题】:Why is the Index of a Pandas DataFrame Slice different to its shape?为什么 Pandas DataFrame Slice 的索引与其形状不同?
【发布时间】:2016-04-14 16:41:48
【问题描述】:

我有一个 DataFrame,df1,它是df 的一部分。 df 是多索引的,形状为 (8,)。切片删除了df 的一些第二级。当我执行df1.shape 时,它返回(4,) - 一切都很好 - 但是当我执行df1.index.levels[0] 时,它返回(4,)。这是怎么回事?

In [ ]:       
arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']),
            np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])]


    df = pd.DataFrame(np.random.randn(8,2), index=arrays)
    df

Out [ ]:
            0        1
bar one   -0.447155  -0.323073
    two    0.115899  -0.015561
baz one   -0.272498  1.847073
    two   -0.399948  -0.264327
foo one    0.169687  -1.708543
    two    1.154434  0.878936
qux one    0.535721  0.437186
    two   -1.203431  0.568412

In [ ]:
    df1=df[df[1]>0]

Out [ ]:
            0           1
    baz one  -0.272498  1.847073
    foo two  1.154434   0.878936
    qux one  0.535721   0.437186
        two  -1.203431  0.568412

现在是奇怪的部分

In [ ]:
    df1=df[df[1]>0]
    print(df1.index.levels[0], df1.index.levels[0].shape)

Out [ ]:
    Index(['bar', 'baz', 'foo', 'qux'], dtype='object') (4,)

我觉得这很奇怪,因为df1 中没有显示bar。这背后的原因是什么?

我的猜测是与复制/不复制有关,但我不明白为什么。

【问题讨论】:

    标签: python pandas indexing dataframe


    【解决方案1】:

    根据docs

    注意 MultiIndex 的 repr 显示索引的所有定义级别,即使它们实际上并未使用。在对索引进行切片时,您可能会注意到这一点。 ...

    这样做是为了避免重新计算关卡以使切片具有高性能。如果您想查看实际使用的级别...

    仅使用已使用的级别重建多索引

    df1.index = pd.MultiIndex.from_tuples(df1.index)
    

    【讨论】:

    • 我想我对多索引的了解还不够多,因此无法考虑查看或知道要查找什么,非常感谢!
    【解决方案2】:

    考虑两个索引:

    In [59]: df.index
    Out[59]: 
    MultiIndex(levels=[[u'bar', u'baz', u'foo', u'qux'], [u'one', u'two']],
               labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]])
    
    In [58]: df1.index
    Out[58]: 
    MultiIndex(levels=[[u'bar', u'baz', u'foo', u'qux'], [u'one', u'two']],
               labels=[[1, 2, 3, 3], [0, 1, 0, 1]])
    

    当使用df1 = df[df[1]>0] 构建df1 时,Pandas 可以通过以下方式构建df1.index 只需更改labels。此外,如果它不改变levels,那么 它不必重新编号labels。这就是为什么df1.index 包含bar 即使df1 不使用bar

    您可以使用reset_index/set_index重建索引:

    In [63]: df1.reset_index().set_index(['level_0', 'level_1']).index
    Out[63]: 
    MultiIndex(levels=[[u'baz', u'foo', u'qux'], [u'one', u'two']],
               labels=[[0, 1, 2, 2], [0, 1, 0, 1]],
               names=[u'level_0', u'level_1'])
    

    -- 或者使用 Alexander's faster solution, df1.index = pd.MultiIndex.from_tuples(df1.index) -- 但是 Pandas 默认情况下不这样做可能是为了获得更好的性能。

    【讨论】:

      【解决方案3】:

      这是因为级别只是标签,它是确定该标签存在哪些标签的第二级值,例如在我的情况下:

      In [2]:
      arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']),
                  np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])]
      ​
      df = pd.DataFrame(np.random.randn(8,2), index=arrays)
      df
      ​
      Out[2]:
                      0         1
      bar one  1.226303  0.017598
          two  0.940893  1.491474
      baz one  0.335430  1.178512
          two -1.006346 -0.733090
      foo one -0.765838 -0.494056
          two -1.744994 -1.001641
      qux one  0.177123 -0.969671
          two  0.544314 -0.026114
      
      In [3]:    
      df1=df[df[1]>0]
      df1.index
      
      Out[3]:
      MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']],
                 labels=[[0, 0, 1], [0, 1, 0]])
      

      给予:

      In [4]:
      df1
      
      Out[4]:
                      0         1
      bar one  1.226303  0.017598
          two  0.940893  1.491474
      baz one  0.335430  1.178512
      

      所以如果你看一下索引:

      MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']],
                     labels=[[0, 0, 1], [0, 1, 0]])
      

      值:labels=[[0, 0, 1], [0, 1, 0] 是存在的级别值中的值,这就是为什么您会看到所有 4 个标签且形状为 4 的原因

      【讨论】:

      • 为了清楚起见,第一部分标签labels=[[0,0,1],...]相当于说“Multiindex level 0 is ['bar', 'bar', 'baz']”?
      • 是的,这是正确的,它是引用级别的索引
      猜你喜欢
      • 2021-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-08
      • 2016-02-17
      • 2021-02-03
      • 2020-11-25
      • 2014-01-25
      相关资源
      最近更新 更多