J'ai un DataFrame avec lequel j'essaie de trouver la fréquence de certains événements. Ainsi, par exemple, il est répertorié comme suit
Month Year Event Count of Events 1 2018 A 02 1 2018 B 00 1 2018 C 00 2 2018 A 00 2 2018 B 00 2 2018 B 01 ...
etc. J'ai tout regroupé par fréquence d'événement par an. Je l'ai fait en utilisant le code suivant.
Cela compte tous les événements pour que je puisse les faire la moyenne
df.groupby(['Event'])['Count of Events'].mean()
Ce qui nous donne quelque chose du genre
Year Month Event Count of Events 2018 01 A 2 2018 02 B 1 ...
Et puis j'obtiens la moyenne de la fréquence à laquelle cela se produit par mois pendant toute l'année en utilisant
df.groupby(['Year','Month','Event'])['Event'].size().rename('Count of Events').reset_index()
Ce qui me donne la moyenne. Cependant, une chose que j'ai remarquée est que j'ai peut-être des lacunes. Par exemple, l'événement «A» peut se produire en janvier et en février, mais pas en mars, donc cela ne me donnera pas une véritable «moyenne» sur l'année. Quelle serait la meilleure façon de «boucher» ces trous? Par exemple, dans la liste d'exemples ci-dessus,
Month Year Event UniqueID 1 2018 A 01 1 2018 A 02 2 2018 B 03 ....
serait le résultat final optimal avant de faire la moyenne. Merci!
3 Réponses :
Je pense que vous avez besoin de fillna: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.fillna.html
C'est un moyen très simple de remplir des valeurs nulles et de désigner avec quoi les remplir.
Je pense que le problème est que certaines combinaisons des colonnes groupby ( Year, Month ) n'apparaissent tout simplement pas dans le DataFrame d'origine, de sorte que le DataFrame résultant manque de lignes entières - - il n'y a aucune valeur np.nan à remplir.
Vous étiez proche de la solution. Après le regroupement, décompressez le dataframe dans un formulaire "large" (de cette façon, vous aurez chaque combinaison d'un mois et d'un an), remplissez les valeurs manquantes avec des 0 et empilez-les:
df.groupby(["Month", "Year", "Event"]).size().unstack().fillna(0).stack() #Month Year Event #1 2018 A 2.0 # B 0.0 #2 2018 A 0.0 # B 1.0
p>
Impressionnant! Merci beaucoup! Existe-t-il un moyen simple de conserver la 4ème colonne (Le décompte "dérivé" de la colonne nommée de cette façon sans utiliser .rename?
La solution proposée par DYZ ne produit des données que pour les mois "présents".
Mais considérez les données source comme ceci:
Count of Events Event A 0.714286 B 0.428571
où il n'y a pas de données pour mars, mai et juin, donc le résultat est imprimé selon DYZ aura des "lacunes".
Notez également qu'un tel détail concernant les "lacunes" est la source des données:
Par exemple dans mon échantillon de données, si le premier événement a eu lieu en janvier et le dernier en juillet, quel que soit le type d'événement , toute l'activité a pris 7 mois.
L'une des étapes devrait donc être de calculer MonthNo code > - le nombre de mois de
toute activité.
Une autre proposition consiste à "passer" de colonnes distinctes Année / Mois à Dat (DateTime) et définissez-le comme index. Cette colonne (en fait l'index) sera nécessaire à un moment donné (voir ci-dessous).
Donc ma proposition pour écrire le script est:
df3.groupby(level=0).sum() / MonthNo
Ensuite, si vous voulez avoir des lignes avec zéro nombre d'événements pour les mois "d'interruption", appel
rééchantillonner pour chaque type d'événement (ici l'index DateTime est nécessaire):
Count of Events
Event Dat
A 2018-01-01 2
2018-02-01 0
2018-03-01 0
2018-04-01 2
2018-05-01 0
2018-06-01 0
2018-07-01 1
B 2018-02-01 1
2018-03-01 0
2018-04-01 0
2018-05-01 0
2018-06-01 0
2018-07-01 2
Le résultat est:
df3 = df2.groupby(['Event']).resample('MS').sum()