Python Pandas按列排序多索引,但保留树结构

时间:2017-11-19 14:46:03

标签: python pandas sorting tree multi-index

使用pandas 0.20.3我试图用一个列('D')对数据帧的n个多级别进行排序,使其值(降序),以保持组的层次结构。

示例输入:

                    D
A     B     C
Gran1 Par1  Child1  3
            Child2  7
            Child3  2
      Par2  Child1  9
            Child2  2
      Par3  Child1  6
Gran2 Par1  Child1  3
      Par2  Child1  8
            Child2  2
            Child3  3
      Par3  Child1  6
            Child2  8

期望的结果:

                    D
A     B     C
Gran2 Par3  Child2  8
            Child1  6
      Par2  Child1  8
            Child3  3
            Child2  2
      Par1  Child1  3
Gran1 Par1  Child2  7
            Child1  3
            Child3  2
      Par2  Child1  9
            Child2  2
      Par3  Child1  6

与排序和排序多级索引相关的其他问题的解决方案似乎集中在排序索引的实际级别或在排序列时按顺序维护它。我没有找到多级排序,其中列的值用于按指定级别的聚合值对索引进行排序。非常感谢任何建议。

2 个答案:

答案 0 :(得分:0)

MultiIndex的列需要reset_indexsum的{​​{3}}列需要transform,然后sort_valuesset_index

df = df.reset_index()
df['G'] = df.groupby(['A','B'])['D'].transform('sum')

df = df.sort_values(['A','G','D'], ascending=False).drop('G',1).set_index(['A','B','C'])
print (df)

                   D
A     B    C        
Gran2 Par3 Child2  8
           Child1  6
      Par2 Child1  8
           Child3  3
           Child2  2
      Par1 Child1  3
Gran1 Par1 Child2  7
           Child1  3
           Child3  2
      Par2 Child1  9
           Child2  2
      Par3 Child1  6

答案 1 :(得分:0)

您需要创建三个单独的数组,并通过它们的组合进行排序。在这个例子中,我使用Numpy的np.lexsort进行排序,然后我使用iloc来尊重那种排序。最后,我使用a[::-1]进行反向排序。

a = np.lexsort([
    df.D.values,
    df.groupby(level=[0, 1]).D.transform('sum').values,
    df.groupby(level=0).D.transform('sum').values
])

df.iloc[a[::-1]]

                   D
A     B    C        
Gran2 Par3 Child2  8
           Child1  6
      Par2 Child1  8
           Child3  3
           Child2  2
      Par1 Child1  3
Gran1 Par1 Child2  7
           Child1  3
           Child3  2
      Par2 Child1  9
           Child2  2
      Par3 Child1  6
相关问题