web-dev-qa-db-fra.com

Tri par valeur absolue sans modifier les données

Je cherche un moyen simple de trier un pandas dataframe par la valeur absolue d'une colonne particulière, mais sans réellement changer les valeurs dans le dataframe. Quelque chose de similaire à sorted(df, key=abs). Donc, si j'avais une trame de données comme:

    a   b
0   1   -3
1   2   5 
2   3   -1
3   4   2
4   5   -9

Les données triées résultantes lors du tri sur 'b' ressembleraient à:

    a   b
2   3   -1
3   4   2
0   1   -3
1   2   5 
4   5   -9
23
afinit

[~ # ~] mise à jour [~ # ~]

Puisque 0.17.0order et sort sont obsolètes (merci @Ruggero Turra), vous pouvez utiliser sort_values pour y parvenir maintenant:

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
31
EdChum

Vers des pandas plus idiomatiques: utilisez argsort

Une approche plus propre serait d'appeler Series.argsort sur les valeurs absolues, puis d'indexer:

df.iloc[df['b'].abs().argsort()]

   a  b
2  3 -1
3  4  2
0  1 -3
1  2  5
4  5 -9

Si vous devez réinitialiser l'index, utilisez 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

Enfin, puisque argsort n'a pas de paramètre ascending pour spécifier l'ordre croissant/décroissant , vous devrez annuler df['b'].abs() pour trier par ordre décroissant.

df.iloc[(-df['b'].abs()).argsort()]

   a  b
4  5 -9
1  2  5
0  1 -3
3  4  2
2  3 -1

Vous pouvez également le faire avec NumPy — utilisez np.abs et 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

Ou, pour ordre décroissant ,

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
6
cs95