我希望能够找到一种简单的方法,按照特定列的绝对值对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
在sort_values()
函数中使用参数key
:
import pandas as pd
df = pd.DataFrame({'A': ['a', 'b', 'c', 'd', 'e', 'f'], 'B': [-3, -2, -1, 0, 1, 2]})
df.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
更新
自从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
df.reindex(df.b.abs().sort_values(ascending=False).index)
。 - PV8argsort
一个更简洁的方法是在绝对值上调用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
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
对于系列数据:
series_name.sort_values(key=abs)
然后将其与数据框相结合:
df.reindex(series_name.sort_values(key=abs).index)
key
关键字参数! - Shan Douttt.sort_values(by='B', key=pd.Series.abs)
也能工作,或许在较旧的 Pandas 版本中也是如此? - Cactus Philosopherkey
参数是“在1.1.0版本中新增的”,该版本于2020年7月28日发布。 - Lucecpkndf['B_abs'] = df['B'].abs()
然后df.sort_values(['B_abs', 'A'])
。 - Lucecpkn