【问题标题】:Mapping row-wise sorted dataframe to original column labels (Pandas)将按行排序的数据帧映射到原始列标签(熊猫)
【发布时间】:2017-08-02 14:23:15
【问题描述】:

我面临这个涉及数据帧的问题,所以在谷歌上花了很多时间之后,我在这里提出一个问题。 我有一个数据框 -

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

我想按降序对每一行进行排序,但不是保存值,我想保存相应的列名。

排序后的数据框看起来像这样 -

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

我最终想要的是下面这个结构,它对应于已排序数据框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

我相信会有一个更简单的单线解决方案来解决这个问题,而无需编写明确的for loop

【问题讨论】:

    标签: python sorting dataframe row


    【解决方案1】:

    你可以使用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.values[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.values[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
    

    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
    

    【讨论】:

    • 它和您的其他解决方案一样有效。非常感谢。
    • 是的,它更快,因为只使用 numpy。
    【解决方案2】:

    应用np.argsort,对索引进行排序,然后索引到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
    

    【讨论】:

    • @OliverS 很高兴我能帮上忙!请记住,如果答案有帮助,您可以accept它。
    • 哦!我是这里的新手,但现在已经“接受”了。再次感谢。
    • @OliverS 没关系。您没有义务这样做,但认为这是一种表达“谢谢”的好方法 :) 您只能将一个答案标记为已接受,因此请始终选择对您帮助最大的答案。
    • 当然可以!会慢慢慢慢习惯stackoverflow的礼仪:)
    【解决方案3】:

    这是一个类似于@COLDSPEED 的解决方案的解决方案——它使用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
    

    【讨论】:

    • 你好 MaxU,您的解决方案同样有效。感谢分享。
    • 可以通过仅具有大于 0 的值的列索引来扩展此问题吗?所以在第二行我们只得到 C D A 和空白空间。在最后一行只有 A。
    • @OliverS,请使用小样本数据集和所需数据集打开一个新问题。更改已回答的问题 - 使给出的答案无效
    • 我刚刚这样做了 Max.
    【解决方案4】:

    这是另一种方式,使用argsortapply

    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
    

    【讨论】:

    • 感谢约翰的解决方案。
    猜你喜欢
    • 2018-01-10
    • 2020-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    • 1970-01-01
    • 2014-06-25
    相关资源
    最近更新 更多