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

Python允许按列对多索引进行排序,但保留树结构,python,pandas,sorting,tree,multi-index,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

使用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
与多级索引排序和排序相关的其他问题的解决方案似乎集中于对索引的实际级别进行排序或在对列进行排序时保持其有序。我没有找到一种多级排序方法,其中列的值用于按该特定级别的聚合值对索引进行排序。非常感谢您的建议。

需要从
多索引
中选择列,然后是
总和
值,最后是:


您需要创建三个单独的数组,并根据它们的组合进行排序。在本例中,我使用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

谢谢很快,但仍然不是我寻求的解决方案。。。注意,例如在GRAN1内,PAR 1中的和大于PAR3中的和,因此应该更高。所以排序应该按照从A到C的顺序进行。希望解释是有意义的…它似乎在我的真实数据集上起作用。。。您确定解决方案中的输出正确吗?它似乎与您的解决方案不匹配。我将尝试看看是否可以将其扩展到更多级别。谢谢实际上,它还不起作用。。。它似乎在我的数据集中按第二列排序,但不按其他列排序。。。还可以使用所需的结果检查不同的输出谢谢!我想我必须努力提高自己的声誉。我担心我提供的例子不太好。您的解决方案对它有效,但在我的较大数据集上不起作用。我有更多的A值,但这些仍然是混乱的。。。由于排序现在不支持该特定级别的“组加载”,因此在此处进行排序的基本原理是什么?
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