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