Search code examples
pythonpandastransformationdata-manipulationmelt

Python - manipulation columns and rows with ordering - reshape


I have a Input dataframe:

import pandas as pd

df = pd.DataFrame({"AX_970" : {0 : 0.7, 1 : 0.1, 2 : 0.2},
                   "AZ_980" : {0 : 0.2, 1 : 0.7, 2 : 0.1},
                   "BV_197" : {0 : 0.5, 1 : 0.2, 2 : 0.3},
                   "BT_980" : {0 : 0.1, 1 : 0.22, 2 : 0.7}
                   })
df["id"] = df.index
df.head()

Input table

    AX_970  AZ_980  BT_980  BV_197  id
0     0.7      0.2     0.1   0.5    0
1     0.1      0.7    0.22   0.2    1
2     0.2      0.1     0.7   0.3    2

I need to transform this input as you can see in below output example:

( Output sorted descending )

        1      2       3       4   id
0   AX_970  BV_197  AZ_980  BT_980  0
1   AZ_980  BT_980  BV_197  AX_970  1
2   BT_980  BV_197  AX_970  AZ_980  2

If you have any ideas please share. Thank you very much!


Solution

  • You can use np.argsort with pd.DataFrame.iloc:

    df.iloc[:, :-1] = df.columns[np.argsort(df.iloc[:, :-1].values, axis=1)[:, ::-1]]
    df.columns[    
    
    print(df)
    
       AX_970  AZ_980  BT_980  BV_197  id
    0  AX_970  BV_197  AZ_980  BT_980   0
    1  AZ_980  BT_980  BV_197  AX_970   1
    2  BT_980  BV_197  AX_970  AZ_980   2
    

    You can rename columns as below. The logic is verbose since you should not update the underlying array in-place, as this may cause side-effects.

    arr = df.columns.values
    arr[:-1] = np.arange(1, len(df.columns))
    df.columns = arr
    
    print(df)
    
            1       2       3       4  id
    0  AX_970  BV_197  AZ_980  BT_980   0
    1  AZ_980  BT_980  BV_197  AX_970   1
    2  BT_980  BV_197  AX_970  AZ_980   2