J'ai un objet Series qui a:
date price
dec 12
may 15
apr 13
..
Problème posé: Je souhaite le faire apparaître par mois, calculer le prix moyen pour chaque mois et le présenter de manière triée par mois.
Sortie désirée:
month mean_price
Jan XXX
Feb XXX
Mar XXX
J'ai pensé faire une liste et la transmettre à une fonction de tri:
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
mais sort_values ne supporte pas cela pour les séries.
Un gros problème que j'ai est que même si
df = df.sort_values(by='date',ascending=True,inplace=True)
fonctionneà la df
initiale, mais après que j’ai fait une groupby
, elle n’a pas maintenu l’ordre sortant de la df
triée.
Pour conclure, j'avais besoin de la trame de données initiale de ces deux colonnes. Trié la colonne datetime et via un groupe en utilisant le mois (dt.strftime ('% B')), le tri s’est égaré. Maintenant, je dois trier par nom de mois.
Mon code:
df # has 5 columns though I need the column 'date' and 'price'
df.sort_values(by='date',inplace=True) #at this part it is sorted according to date, great
total=(df.groupby(df['date'].dt.strftime('%B'))['price'].mean()) # Though now it is not as it was but instead the months appear alphabetically
Merci @Brad Solomon pour avoir offert un moyen plus rapide de capitaliser les chaînes!
Note 1 La réponse de Brad Solomon utilisant pd.categorical
devrait économiser davantage vos ressources que ma réponse. Il a montré comment assigner un ordre à vos données catégoriques. Vous ne devriez pas le manquer: P
Alternativement, vous pouvez utiliser.
df = pd.DataFrame([["dec", 12], ["jan", 40], ["mar", 11], ["aug", 21],
["aug", 11], ["jan", 11], ["jan", 1]],
columns=["Month", "Price"])
# Preprocessing: capitalize `jan`, `dec` to `Jan` and `Dec`
df["Month"] = df["Month"].str.capitalize()
# Now the dataset should look like
# Month Price
# -----------
# Dec XX
# Jan XX
# Apr XX
# make it a datetime so that we can sort it:
# use %b because the data use the abbriviation of month
df["Month"] = pd.to_datetime(df.Month, format='%b', errors='coerce').dt.month
df = df.sort_values(by="Month")
total = (df.groupby(df['Month"])['Price'].mean())
# total
Month
1 17.333333
3 11.000000
8 16.000000
12 12.000000
Note 2groupby
par défaut triera les clés de groupe pour vous. Sachez que vous devez utiliser la même clé pour trier et grouper dans les fonctions df = df.sort_values(by=SAME_KEY)
et total = (df.groupby(df[SAME_KEY])['Price'].mean()).
. Sinon, vous risquez d’obtenir un comportement inattendu. Voir Groupby préserver l'ordre parmi les groupes? De quelle manière? Pour plus d'informations.
Note 3 Une méthode plus efficace en calcul consiste à calculer la moyenne puis à effectuer le tri par mois. De cette manière, il vous suffit de trier sur 12 éléments plutôt que sur la totalité de la variable df
. Cela réduira les coûts de calcul si vous n'avez pas besoin de df
pour être trié.
Note 4 Pour les personnes ayant déjà month
comme index, et vous demandez comment le rendre catégorique, jetez un coup d'œil à pandas .CategoricalIndex
jezrael a un exemple concret sur la commande par index in Les séries de pandas sont triées par mois
Vous pouvez utiliser des données catégoriques pour permettre un tri correct:
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
df['months'] = pd.Categorical(df['months'], categories=months, ordered=True)
df.sort_values(...) # same as you have now; can use inplace=True
Lorsque vous spécifiez les catégories, les pandas mémorisent l'ordre de spécification comme ordre de tri par défaut.
Docs: Catégories de pandas> tri et ordre .
utilisez Sort_Dataframeby_Month function pour trier les noms de mois par ordre chronologique
Les paquets doivent être installés.
$ pip install sorted-months-weekdays
$ pip install sort-dataframeby-monthorweek
exemple:
from sorted_months_weekdays import *
from sort_dataframeby_monthorweek import *
df = pd.DataFrame([['Jan',23],['Jan',16],['Dec',35],['Apr',79],['Mar',53],['Mar',12],['Feb',3]], columns=['Month','Sum'])
df
Out[11]:
Month Sum
0 Jan 23
1 Jan 16
2 Dec 35
3 Apr 79
4 Mar 53
5 Mar 12
6 Feb 3
Pour trier dataframe par mois, utilisez la fonction ci-dessous
Sort_Dataframeby_Month(df=df,monthcolumnname='Month')
Out[14]:
Month Sum
0 Jan 23
1 Jan 16
2 Feb 3
3 Mar 53
4 Mar 12
5 Apr 79
6 Dec 35
Vous pouvez ajouter la valeur numérique du mois avec le nom dans l'index ("01 janvier"), faire un tri puis supprimer le nombre
total=(df.groupby(df['date'].dt.strftime('%m %B'))['price'].mean()).sort_index()
Cela peut ressembler à ça:
01 January xxx
02 February yyy
03 March zzz
04 April ttt
total.index = [ x.split()[1] for x in total.index ]
January xxx
February yyy
March zzz
April ttt