我想对每行的值进行排序,并按列名替换值。 假设我们有下面的数据框。
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)
但它对我不起作用。
答案 0 :(得分:4)
您可以使用numpy.argsort
,但首先通过set_index
将ID
列添加到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)
请注意,按行应用时,每行的索引是数据框的列。