I have a dataframe with similar row and column labels just like any other square matrix as it follows:
a b c d e f
a 1 1 0 1 0 1
b 0 0 0 0 0 1
c 0 1 1 0 1 0
d 1 0 0 1 1 0
e 0 1 1 0 0 0
f 0 0 0 1 0 1
How to convert this dataframe into another form (by rearranging rows and columns) where all the non-zero diagonal elements are all in the lower block and zero diagonal elements in the upper block? In other words, the matrix has been permuted so that "1" diagonal elements are in the lower block and the "0" diagonal elements are in upper block such as the following:
b e a c d f
b 0 0 0 0 0 1
e 1 0 0 1 0 0
a 1 0 1 0 1 1
c 1 1 0 1 0 0
d 0 1 1 0 1 0
f 0 0 0 0 1 1
CodePudding user response:
IIUC, you can extract the diagonal of the underlying numpy array and get the sorted order with numpy.argsort
, then slice with iloc
:
import numpy as np
order = np.argsort(df.to_numpy().diagonal())
df2 = df.iloc[order, order]
output:
b e a c d f
b 0 0 0 0 0 1
e 1 0 0 1 0 0
a 1 0 1 0 1 1
c 1 1 0 1 0 0
d 0 1 1 0 1 0
f 0 0 0 0 1 1