web-dev-qa-db-fra.com

Comment trier pandas trame de données en utilisant les valeurs de plusieurs colonnes?

J'ai le cadre de données suivant:

df = pandas.DataFrame([{'c1':3,'c2':10},{'c1':2, 'c2':30},{'c1':1,'c2':20},{'c1':2,'c2':15},{'c1':2,'c2':100}])

Ou, sous forme lisible par l'homme:

   c1   c2
0   3   10
1   2   30
2   1   20
3   2   15
4   2  100

La commande de tri suivante fonctionne comme prévu:

df.sort(['c1','c2'], ascending=False)

Sortie:

   c1   c2
0   3   10
4   2  100
1   2   30
3   2   15
2   1   20

Mais la commande suivante:

df.sort(['c1','c2'], ascending=[False,True])

résulte en

   c1   c2
2   1   20
3   2   15
1   2   30
4   2  100
0   3   10

et ce n'est pas ce que j'attends. Je m'attends à ce que les valeurs de la première colonne soient ordonnées du plus grand au plus petit et, s'il existe des valeurs identiques dans la première colonne, classer les valeurs par ordre croissant dans la deuxième colonne.

Est-ce que quelqu'un sait pourquoi cela ne fonctionne pas comme prévu?

AJOUTÉ

C'est un copier-coller:

>>> df.sort(['c1','c2'], ascending=[False,True])
   c1   c2
2   1   20
3   2   15
1   2   30
4   2  100
0   3   10
59
Roman

DataFrame.sort est obsolète; utilisation DataFrame.sort_values .

>>> df.sort_values(['c1','c2'], ascending=[False,True])
   c1   c2
0   3   10
3   2   15
1   2   30
4   2  100
2   1   20
>>> df.sort(['c1','c2'], ascending=[False,True])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/ampawake/anaconda/envs/pseudo/lib/python2.7/site-packages/pandas/core/generic.py", line 3614, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'DataFrame' object has no attribute 'sort'
69
falsetru

L'utilisation de sort peut entraîner un message d'avertissement. Voir github discussion. Donc, vous voudrez peut-être utiliser sort_values, docs ici

Ensuite, votre code peut ressembler à ceci:

df = df.sort_values(by=['c1','c2'], ascending=[False,True])
24
HonzaB

Si je comprends bien, la méthode dataframe.sort () est obsolète dans pandas> 0.18. Pour résoudre votre problème, vous devez utiliser dataframe.sort_values ​​() à la place:

f.sort_values(by=["c1","c2"], ascending=[False, True])

La sortie ressemble à ceci:

    c1  c2
    3   10
    2   15
    2   30
    2   100
    1   20
8
fotis j

Dans mon cas, la réponse acceptée n'a pas fonctionné:

f.sort_values ​​(by = ["c1", "c2"], croissant = [False, True])

Seuls les éléments suivants ont fonctionné comme prévu:

f = f.sort_values(by=["c1","c2"], ascending=[False, True])
4
Pedro Lobito

Si vous écrivez ce code en tant que fichier de script, vous devrez l'écrire comme ceci:

df = df.sort(['c1','c2'], ascending=[False,True])
2
Akash

Note: Tout est correct ici, il suffit de remplacer sort -> sort_values ​​ () Alors, cela devient:

 import pandas as pd
 df = pd.read_csv('data.csv')
 df.sort_values(ascending=False,inplace=True)

Référez-vous au site officiel ici .

1
siddesh chavan

J'ai trouvé cela très utile:

df = pd.DataFrame({'A' : range(0,10) * 2, 'B' : np.random.randint(20,30,20)})

# A ascending, B descending
df.sort(**skw(columns=['A','-B']))

# A descending, B ascending
df.sort(**skw(columns=['-A','+B']))

Notez que contrairement à la norme columns=,ascending= arguments, ici les noms de colonne et leur ordre de tri sont au même endroit. En conséquence, votre code devient beaucoup plus facile à lire et à maintenir.

Notez l'appel réel à .sort est inchangé, skw (s ort kw args) n’est qu’une petite fonction d’aide qui analyse les colonnes et retourne le columns= et ascending= paramètres pour vous. Passez-le comme vous le feriez d'habitude. Copiez/collez le code suivant dans, par exemple, votre local utils.py puis oubliez-le et utilisez-le comme ci-dessus.

# utils.py (or anywhere else convenient to import)
def skw(columns=None, **kwargs):
    """ get sort kwargs by parsing sort order given in column name """
    # set default order as ascending (+)
    sort_cols = ['+' + col if col[0] != '-' else col for col in columns]
    # get sort kwargs
    columns, ascending = Zip(*[(col.replace('+', '').replace('-', ''), 
                                False if col[0] == '-' else True) 
                               for col in sort_cols])
    kwargs.update(dict(columns=list(columns), ascending=ascending))
    return kwargs
1
miraculixx