【问题标题】:Sorting Multi-Index to full depth (Pandas)将多索引排序到全深度(熊猫)
【发布时间】:2019-08-10 03:08:23
【问题描述】:

我有一个数据框,我从 csv 文件加载,然后通过 set_index 方法将索引设置为它的几列(通常是两列或三列)。这个想法是然后使用几个组合键访问部分数据帧,例如:

df.set_index(['fileName','phrase'])
df.ix['somePath','somePhrase']

显然,只有当数据帧的MultiIndex 被排序到足够的深度时,这种具有多个键的选择才有可能。在这种情况下,由于我提供了两个键,所以 .ix 操作只有在数据帧 MultiIndex 被排序到至少 2 的深度时才会失败。

由于某种原因,当我如图所示设置索引时,对我来说似乎两个图层都已排序,调用 df.index.lexsort_depth 命令返回 1 ,并且尝试使用两个键访问时出现以下错误:

MultiIndex lexsort 深度为 1,键为长度 2

有什么帮助吗?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    这不是很清楚你在问什么。多索引文档是here

    OP需要设置索引,然后就地排序

    df.set_index(['fileName','phrase'],inplace=True)
    df.sortlevel(inplace=True)
    

    然后通过元组访问这些级别以获得特定的结果

    df.ix[('somePath','somePhrase')]
    

    也许只是举一个像这样的玩具例子,表明我想得到一个特定的结果。

    In [1]: arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'])
       ...:    .....: ,
       ...:    .....:           np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])
       ...:    .....:           ]
    
    In [2]: df = DataFrame(randn(8, 4), index=arrays)
    
    In [3]: df
    Out[3]: 
                    0         1         2         3
    bar one  1.654436  0.184326 -2.337694  0.625120
        two  0.308995  1.219156 -0.906315  1.555925
    baz one -0.180826 -1.951569  1.617950 -1.401658
        two  0.399151 -1.305852  1.530370 -0.132802
    foo one  1.097562  0.097126  0.387418  0.106769
        two  0.465681  0.270120 -0.387639 -0.142705
    qux one -0.656487 -0.154881  0.495044 -1.380583
        two  0.274045 -0.070566  1.274355  1.172247
    
    In [4]: df.index.lexsort_depth
    Out[4]: 2
    
    In [5]: df.ix[('foo','one')]
    Out[5]: 
    0    1.097562
    1    0.097126
    2    0.387418
    3    0.106769
    Name: (foo, one), dtype: float64
    
    In [6]: df.ix['foo']
    Out[6]: 
                0         1         2         3
    one  1.097562  0.097126  0.387418  0.106769
    two  0.465681  0.270120 -0.387639 -0.142705
    
    In [7]: df.ix[['foo']]
    Out[7]: 
                    0         1         2         3
    foo one  1.097562  0.097126  0.387418  0.106769
        two  0.465681  0.270120 -0.387639 -0.142705
    
    In [8]: df.sortlevel(level=1)
    Out[8]: 
                    0         1         2         3
    bar one  1.654436  0.184326 -2.337694  0.625120
    baz one -0.180826 -1.951569  1.617950 -1.401658
    foo one  1.097562  0.097126  0.387418  0.106769
    qux one -0.656487 -0.154881  0.495044 -1.380583
    bar two  0.308995  1.219156 -0.906315  1.555925
    baz two  0.399151 -1.305852  1.530370 -0.132802
    foo two  0.465681  0.270120 -0.387639 -0.142705
    qux two  0.274045 -0.070566  1.274355  1.172247
    
    In [10]: df.sortlevel(level=1).index.lexsort_depth
    Out[10]: 0
    

    【讨论】:

    • 我以为我很清楚。我已经看到您链接到的文档,它没有帮助。当您尝试使用其键访问特定行时,问题就开始了。如果索引未按所有级别排序,则会出现错误。问题是如何对所有级别的索引进行排序
    • 只是df.sortlevel()
    • 我做了,它不能正常工作。当我按“文件名”排序级别时,外部索引被排序,内部(“短语”)被混合。当我按“短语”排序级别时,外层(“文件名”)被混合,而内层被排序。在这两种情况下,排序深度都是 1,这使我无法使用两个键访问 df。我需要一些方法来对外部索引进行排序,然后 然后 对内部索引进行排序而不改变外部索引的顺序。即 - 我需要两层排序。
    • 您必须展示一个失败的完整示例; sortlevel 按级别排序,然后是后续级别
    • set_index 不排序,因为理论上它可能是一项昂贵的操作。这就是为什么其中一些目前是“手动”的。
    【解决方案2】:

    我意识到已经过去了一段时间,但我似乎遇到了与@idoda 相同的问题,当数据帧可能在列和索引上都有多个索引时,接受的答案不适用于 MultiIndex 数据帧。此处当前未显示的技巧是有一个“轴”选项,默认为零,但也可以设置为 1。

    例如,如果您尝试:

    df.sortlevel(inplace=True,sort_remaining=True)
    

    并且仍然遇到 lexsort 错误,知道它们是其中的默认“axis = 0”kwarg 可能相关。因此您也可以尝试添加

    df.sortlevel(axis=1,inplace=True,sort_remaining=True)
    

    哪个应该排序另一个方向。如果你不想考虑它,你可以用暴力破解它:

    df.sortlevel(axis=0,inplace=True,sort_remaining=True)
    df.sortlevel(axis=1,inplace=True,sort_remaining=True)
    

    这应该对所有级别的列和行索引进行完全排序。我在这里遇到了同样的问题,无法通过建议的答案获得完整的 lexsort,但一些研究表明,即使使用“sort_remaining”True,sortlevel 也仅适用于单个轴。这些 sn-ps 是当前 pythonic 原生答案的解决方案。希望有人觉得它有帮助!

    【讨论】:

    • sortlevel 已被弃用 - 有没有办法用 sort_index 做到这一点?
    【解决方案3】:

    熊猫提供:

    d = d.sort_index()
    print d.index.is_lexsorted() # Sometimes true
    

    在大多数情况下,它会做你想做的事。 但是,始终对索引进行排序,但可能会将其保留为“lexsorted”(例如,如果索引中有 NAN),generates a PerformanceWarning

    为了避免这种情况:

    d = d.sort_index(level=d.index.names)
    print d.index.is_lexsorted() #  true
    

    ...虽然似乎没有记录为什么会有差异。

    【讨论】:

      猜你喜欢
      • 2017-03-17
      • 2017-04-12
      • 2018-10-30
      • 1970-01-01
      • 2016-10-16
      • 2019-01-19
      • 1970-01-01
      • 1970-01-01
      • 2020-10-10
      相关资源
      最近更新 更多