如何对行值进行排序并将其替换为pandas数据帧上的列名

时间:2016-12-13 09:30:01

标签: python python-3.x pandas dataframe reshape

我想对每行的值进行排序,并按列名替换值。 假设我们有下面的数据框。

ID   A    B    C
1    8    10   9
2    6    7    8
3    13   14   7

我希望将其转换为此表单。

 1    B    C    A
 2    c    B    A
 3    B    A    C

有没有办法在python中做到这一点?

我在考虑这样的事情:

df.sort(0, ascending=False)

但它对我不起作用。

2 个答案:

答案 0 :(得分:4)

您可以使用numpy.argsort,但首先通过set_indexID列添加到index

df = df.set_index('ID')

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

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

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

    0  1  2
ID         
1   B  C  A
2   C  B  A
3   B  A  C    

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

   ID  0  1  2
0   1  B  C  A
1   2  C  B  A
2   3  B  A  C  

如果需要设置原始DataFrame的列:

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

    A  B  C
ID         
1   B  C  A
2   C  B  A
3   B  A  C        

<强>计时

#[3 rows x 3 columns]

In [97]: %timeit (pd.DataFrame(df.columns[np.argsort(-df.values, axis=1)],index=df.index, columns=df.columns))
10000 loops, best of 3: 126 µs per loop

In [98]: %timeit (df.apply(lambda row: row.sort_values(ascending=False).index, axis=1))
1000 loops, best of 3: 1.95 ms per loop   
#[30000 rows x 3 columns]
df = pd.concat([df]*10000).reset_index(drop=True)    
#print (df)

df = df.set_index('ID')

In [103]: %timeit (pd.DataFrame(df.columns[np.argsort(-df.values, axis=1)],index=df.index, columns=df.columns))
1000 loops, best of 3: 1.76 ms per loop

In [104]: %timeit (df.apply(lambda row: row.sort_values(ascending=False).index, axis=1))
1 loop, best of 3: 7.21 s per loop              

答案 1 :(得分:1)

我们的想法是对每一行进行排序并获取结果索引。

df.apply(lambda row: row.sort_values(ascending=False).index, axis=1)

请注意,按行应用时,每行的索引是数据框的列。