在Pandas 0.17中,我尝试按特定列排序,同时保持层次索引(A和B)。 B是通过串联设置数据帧时创建的运行编号。我的数据如下:
C D
A B
bar one shiny 10
two dull 5
three glossy 8
foo one dull 3
two shiny 9
three matt 12
这就是我需要的:
C D
A B
bar two dull 5
three glossy 8
one shiny 10
foo one dull 3
three matt 12
two shiny 9
以下是我使用的代码和结果。注意:Pandas 0.17会警告dataframe.sort将被弃用。
df.sort_values(by="C", ascending=True)
C D
A B
bar two dull 5
foo one dull 3
bar three glossy 8
foo three matt 12
bar one shiny 10
foo two shiny 9
添加.groupby会产生相同的结果:
df.sort_values(by="C", ascending=True).groupby(axis=0, level=0, as_index=True)
同样,首先切换到排序索引,然后按列分组并不富有成效:
df.sort_index(axis=0, level=0, as_index=True).groupby(C, as_index=True)
我不确定重建索引我需要保留第一个索引A,第二个索引B可以重新分配,但不必。如果没有简单的解决方案,我会感到惊讶;我想我只是找不到它。任何建议都表示赞赏。
编辑:在此期间我删除了第二个索引B,将第一个索引A重新分配为一列而不是一个排序多列的索引,然后重新索引它:
df.index = df.index.droplevel(1)
df.reset_index(level=0, inplace=True)
df_sorted = df.sort_values(["A", "C"], ascending=[1,1]) #A is a column here, not an index.
df_reindexed = df_sorted.set_index("A")
仍然非常冗长。
答案 0 :(得分:7)
感觉可能有更好的方法,但这是一种方法:
In [163]: def sorter(sub_df):
...: sub_df = sub_df.sort_values('C')
...: sub_df.index = sub_df.index.droplevel(0)
...: return sub_df
In [164]: df.groupby(level='A').apply(sorter)
Out[164]:
C D
A B
bar two dull 5
three glossy 8
one shiny 10
foo one dull 3
three matt 12
two shiny 9
答案 1 :(得分:1)
基于chrisb的代码:
请注意,在我的情况下,它是一个Series而不是DataFrame,
s.groupby(level='A', group_keys=False).apply(lambda x: x.sort_values(ascending=False))