我正在寻找一种简单的方法来按特定列的绝对值对pandas数据帧进行排序,但不会实际更改数据帧中的值。与sorted(df, key=abs)
类似的东西。所以,如果我有一个数据框,如:
a b
0 1 -3
1 2 5
2 3 -1
3 4 2
4 5 -9
在“b”上排序时得到的排序数据如下所示:
a b
2 3 -1
3 4 2
0 1 -3
1 2 5
4 5 -9
答案 0 :(得分:27)
<强>更新强>
由于0.17.0
order
和sort
已被弃用(感谢@Ruggero Turra),您现在可以使用sort_values
来实现此目的:
In[16]:
df.reindex(df.b.abs().sort_values().index)
Out[16]:
a b
2 3 -1
3 4 2
0 1 -3
1 2 5
4 5 -9
答案 1 :(得分:12)
在sort_values()
function中使用参数key
:
import pandas as pd
ttt = pd.DataFrame({'A': ['a', 'b', 'c', 'd', 'e', 'f'], 'B': [-3, -2, -1, 0, 1, 2]})
ttt.sort_values(by='B', key=abs)
将产生:
A B
3 d 0
2 c -1
4 e 1
1 b -2
5 f 2
0 a -3
答案 2 :(得分:2)
在v0.17 +中,不推荐使用sort
和order
。一种更干净的方法是对绝对值调用Series.argsort
,然后进行索引:
df.iloc[df['b'].abs().argsort()]
a b
2 3 -1
3 4 2
0 1 -3
1 2 5
4 5 -9
如果您需要重置索引,请使用Series.reset_index
,
df.iloc[df['b'].abs().argsort()].reset_index(drop=True)
a b
0 3 -1
1 4 2
2 1 -3
3 2 5
4 5 -9
最后,由于argsort
没有一个ascending
参数来指定升序/降序,因此您需要对df['b'].abs()
求反,以降序排序
df.iloc[(-df['b'].abs()).argsort()]
a b
4 5 -9
1 2 5
0 1 -3
3 4 2
2 3 -1
您也可以使用NumPy进行此操作-使用np.abs
和ndarray.argsort
。
df.iloc[np.abs(df['b'].values).argsort()]
a b
2 3 -1
3 4 2
0 1 -3
1 2 5
4 5 -9
或者,对于降序顺序,
df.iloc[(-np.abs(df['b'].values)).argsort()]
a b
4 5 -9
1 2 5
0 1 -3
3 4 2
2 3 -1