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

Python Pandas sorting multiindex by column, but retain tree structure

使用 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

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

需要reset_index for columns from MultiIndex, then transform for sum values and then sort_values and last set_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

您需要创建三个单独的数组并按所有数组的组合进行排序。在此示例中,我使用 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