Comment grouper DataFrame par une période de temps?
J'ai des données à partir de fichiers journaux et je voudrais regrouper les entrées d'une minute:
def gen(date, count=10):
while count > 0:
yield date, "event{}".format(randint(1,9)), "source{}".format(randint(1,3))
count -= 1
date += DateOffset(seconds=randint(40))
df = DataFrame.from_records(list(gen(datetime(2012,1,1,12, 30))), index='Time', columns=['Time', 'Event', 'Source'])
Df:
Event Source
2012-01-01 12:30:00 event3 source1
2012-01-01 12:30:12 event2 source2
2012-01-01 12:30:12 event2 source2
2012-01-01 12:30:29 event6 source1
2012-01-01 12:30:38 event1 source1
2012-01-01 12:31:05 event4 source2
2012-01-01 12:31:38 event4 source1
2012-01-01 12:31:44 event5 source1
2012-01-01 12:31:48 event5 source2
2012-01-01 12:32:23 event6 source1
J'ai essayé ces options:
- {[3] } est un niveau trop élevé et veut agréger.
-
df.groupby(date_range(datetime(2012,1,1,12, 30), freq='Min', periods=4))
échoue avec exception. -
df.groupby(TimeGrouper(freq='Min'))
fonctionne bien et renvoie un objetDataFrameGroupBy
pour un traitement ultérieur, par exemple:grouped = df.groupby(TimeGrouper(freq='Min')) grouped.Source.value_counts() 2012-01-01 12:30:00 source1 1 2012-01-01 12:31:00 source2 2 source1 2 2012-01-01 12:32:00 source2 2 source1 2 2012-01-01 12:33:00 source1 1
Cependant, le TimeGrouper
classe n'est pas documentée.
Quelle est la bonne façon de grouper par un point de temps? Comment puis-je regrouper les données par une minute et par la colonne Source, par exemple groupby([TimeGrouper(freq='Min'), df.Source])
?
2 réponses
Vous pouvez grouper sur n'importe quel tableau/série de la même longueur que votre DataFrame --- même un facteur calculé qui n'est pas réellement une colonne du DataFrame. Donc, pour grouper par minute, Vous pouvez faire:
df.groupby(df.index.map(lambda t: t.minute))
Si vous voulez grouper par minute et autre chose, mélangez simplement ce qui précède avec la colonne que vous voulez utiliser:
df.groupby([df.index.map(lambda t: t.minute), 'Source'])
Personnellement, je trouve utile d'ajouter simplement des colonnes au DataFrame pour stocker certaines de ces choses calculées (par exemple, une colonne "Minute") si je veux les regrouper souvent, car rend le code de regroupement moins verbeux.
, Ou vous pouvez essayer quelque chose comme ceci:
df.groupby([df['Source'],pd.TimeGrouper(freq='Min')])
Puisque la réponse originale est plutôt ancienne et que les pandas ont introduit périodes une solution différente est de nos jours:
df.groupby(df.index.to_periods('T'))
De plus, vous pouvez rééchantillonner
df.resample('T')