Mapping row-wise sorted dataframe to original column labels (Pandas)

狂风中的少年 提交于 2020-01-15 06:31:08

问题


I am facing this problem involving dataframes, so after spending a lot of time on Google, I am opening a question here. I am having a Dataframe -

df 
   A  B  C   D
0  8  3  6   2
1  1 -3  5   2
2  4  9  5  10
3  2 -4 -8  -2

I want to sort every row in descending order, but instead of saving the values, I want to save the corresponding column name.

Sorted dataframe would look like this -

df 
       A  B  C   D
    0  8  6  3   2
    1  5  2  1  -3
    2 10  9  5   4
    3  2 -2 -4  -8

What I ultimately want is this structure below, which corresponds to the column indices of the sorted dataframe df -

df_col 
       1  2  3   4
    0  A  C  B   D
    1  C  D  A   B
    2  D  B  C   A
    3  A  D  B   C

I am sure there will be a simpler one liner solution to this problem, without coding an explicit for loop


回答1:


Apply np.argsort, sort the indices, and then index into df.columns.

In [129]: pd.DataFrame(df.columns[df.apply(np.argsort, axis=1).T[::-1].T])
Out[129]: 
   0  1  2  3
0  A  C  B  D
1  C  D  A  B
2  D  B  C  A
3  A  D  B  C



回答2:


You can use numpy.argsort:

print (np.argsort(-df.values, axis=1))
[[0 2 1 3]
 [2 3 0 1]
 [3 1 2 0]
 [0 3 1 2]]

print (df.columns[np.argsort(-df.values, axis=1)])
Index([['A', 'C', 'B', 'D'], ['C', 'D', 'A', 'B'], ['D', 'B', 'C', 'A'],
       ['A', 'D', 'B', 'C']],
      dtype='object')

print (pd.DataFrame(df.columns[np.argsort(-df.values, axis=1)], 
                               index=df.index))

   0  1  2  3
0  A  C  B  D
1  C  D  A  B
2  D  B  C  A
3  A  D  B  C

Or pandas solution with apply:

print (df.apply(lambda x: x.sort_values(ascending=False).index, axis=1))
   A  B  C  D
0  A  C  B  D
1  C  D  A  B
2  D  B  C  A
3  A  D  B  C



回答3:


Here is a solution similar to @COLDSPEED's solution - it uses Series.argsort:

In [130]: df.apply(lambda x: df.columns[x.argsort()[::-1]], axis=1)
Out[130]:
   A  B  C  D
0  A  C  B  D
1  C  D  A  B
2  D  B  C  A
3  A  D  B  C



回答4:


Here's another way, using argsort and apply

In [1000]: np.argsort(-df, axis=1).apply(lambda x: x.index[x], axis=1)
Out[1000]:
   A  B  C  D
0  A  C  B  D
1  C  D  A  B
2  D  B  C  A
3  A  D  B  C


来源:https://stackoverflow.com/questions/45463536/mapping-row-wise-sorted-dataframe-to-original-column-labels-pandas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!