多级索引排序至完整深度(Pandas)

18

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

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

显然,只有在数据框的MultiIndex按足够深度排序时才能使用多个键进行选择。在这种情况下,由于我提供了两个键,只有当数据框MultiIndex排序到至少深度为2时,.ix操作才不会失败。

出于某种原因,当我设置索引如所示时,虽然我认为两层都已排序,但调用df.index.lexsort_depth命令返回1,并且在尝试使用两个键访问时出现以下错误:

  

MultiIndex lexsort depth 1, key was length 2

需要帮助吗?

3个回答

11

您的问题不太清楚。多重索引文档在这里

原帖作者需要设置索引,然后就地排序。

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

1
我以为我说得很清楚了。我已经看过你提供的文档,但它并没有帮助到我。问题出现在当你尝试使用特定键访问某一行时。如果索引没有按所有级别排序,就会出现错误。问题是如何对所有级别进行索引排序。 - idoda
只需输入“df.sortlevel()”。 - Jeff
我尝试过了,但它不能正常工作。当我按“fileName”排序级别时,外部索引被排序,而内部(“phrase”)则混乱。当我按“phrase”排序级别时,外层级别(“fileName”)被混淆,而内层级别则被排序。在这两种情况下,排序的深度为1,这使我无法使用两个键访问df。我需要一种方法来对外部索引进行排序,然后对内部索引进行排序,而不改变外部索引的顺序。即 - 我需要两层排序。 - idoda
请提供一个完整的失败示例;“sortlevel”按级别排序,然后按后续级别排序。 - Jeff
1
set_index不排序,因为在理论上它可能是一项昂贵的操作。这就是为什么目前有些部分是“手动”的原因。 - Jeff
显示剩余3条评论

4
我知道时间过去了,但我好像遇到了与@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也仅适用于单个轴。以下代码片段是解决这个问题的当前Pythonic本地答案。希望对某人有所帮助!


sortlevel已被弃用 - 是否有使用sort_index的方法来完成这个操作? - Takver

3
Pandas 提供以下功能:
d = d.sort_index()
print d.index.is_lexsorted() # Sometimes true

在大多数情况下,这将完成您想要的操作。

然而,始终对索引进行排序,但可以将其保留为'lexsorted'(例如,如果索引中有NAN),这会生成一条性能警告

为避免此问题:

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

尽管为什么存在差异似乎没有记录,但需要注意的是这两者之间存在差异。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接