2016-08-30 2 views
2

Je voudrais sélectionner les entrées supérieures dans une base de données Pandas sur les entrées d'une colonne spécifique en utilisant df_selected = df_targets.head(N).Pandas DataFrame tri par colonne catégorielle mais par ordre de classe spécifique

Chaque entrée a une valeur target (par ordre d'importance):

Likely Supporter, GOTV, Persuasion, Persuasion+GOTV 

Malheureusement, si je

df_targets = df_targets.sort("target") 

l'ordre alphabétique sera (GOTV, Likely Supporter, ...).

J'espérais un mot-clé comme list_ordering comme dans:

my_list = ["Likely Supporter", "GOTV", "Persuasion", "Persuasion+GOTV"] 
df_targets = df_targets.sort("target", list_ordering=my_list) 

Pour faire face à ce problème, je crée un dictionnaire:

dict_targets = OrderedDict() 
dict_targets["Likely Supporter"] = "0 Likely Supporter" 
dict_targets["GOTV"] = "1 GOTV" 
dict_targets["Persuasion"] = "2 Persuasion" 
dict_targets["Persuasion+GOTV"] = "3 Persuasion+GOTV" 

, mais il semble comme une approche non pythonique.

Des suggestions seraient grandement appréciées!

+0

vous dire 'OrderedDict' droite? –

+0

Lire [cette partie] (http://pandas.pydata.org/pandas-docs/stable/categorical.html#reordering) de la documentation. – IanS

+0

Oui, 'OrderedDict' – elzurdo

Répondre

1

Je pense que vous avez besoin Categorical avec le paramètre ordered=True puis le tri par sort_values travaux très agréable:

import pandas as pd 

df = pd.DataFrame({'a': ['GOTV', 'Persuasion', 'Likely Supporter', 
         'GOTV', 'Persuasion', 'Persuasion+GOTV']}) 

df.a = pd.Categorical(df.a, 
         categories=["Likely Supporter","GOTV","Persuasion","Persuasion+GOTV"], 
         ordered=True) 

print (df) 
        a 
0    GOTV 
1  Persuasion 
2 Likely Supporter 
3    GOTV 
4  Persuasion 
5 Persuasion+GOTV 

print (df.a) 
0    GOTV 
1   Persuasion 
2 Likely Supporter 
3    GOTV 
4   Persuasion 
5  Persuasion+GOTV 
Name: a, dtype: category 
Categories (4, object): [Likely Supporter < GOTV < Persuasion < Persuasion+GOTV] 
df.sort_values('a', inplace=True) 
print (df) 
        a 
2 Likely Supporter 
0    GOTV 
3    GOTV 
1  Persuasion 
4  Persuasion 
5 Persuasion+GOTV 
+0

Merci! (J'ai donné un +1, mais je suis un nouveau, donc peut ne pas le voir dans un moment ...) Une question à propos de 'pd.Categorical'. Cela devrait être une colonne dans un DataFrame beaucoup plus grand, mais 'pd.Categorical' n'est pas une série (il ne prendra pas d'index) Est-ce que ma seule option pour l'envelopper avec' pd.Series' et y appliquer les index? – elzurdo

+0

Si ma réponse était utile, n'oubliez pas [accepter] (http://meta.stackexchange.com/a/5235/295067). Merci. – jezrael

+0

Je pense que vous avez besoin de 'Series', si besoin indices [Plus d'infos sur Categorical] (http://pandas.pydata.org/pandas-docs/stable/categorical.html#object-creation). – jezrael

1

Grâce à l'entrée de jerzrael et références,

J'aime cette solution en tranches:

list_ordering = ["Likely Supporter","GOTV","Persuasion","Persuasion+GOTV"] 

df["target"] = df["target"].astype("category", categories=list_ordering, ordered=True) 
0

La méthode indiquée dans ma réponse précédente est maintenant obsolète.

Au lieu de cela, il est préférable d'utiliser pandas.Categorical comme indiqué here.

Alors:

list_ordering = ["Likely Supporter","GOTV","Persuasion","Persuasion+GOTV"] 
df["target"] = pd.Categorical(df["target"], categories=list_ordering)