Ik heb wat gegevens uit logbestanden en wil de gegevens per minuut groeperen:
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
Ik heb deze opties geprobeerd:
df.resample('Min')
is te hoog niveau en wil aggregeren.df.groupby(date_range(datetime(2012,1,1,12, 30), freq='Min',
mislukt met uitzondering.
periods=4))-
df.groupby(TimeGrouper(freq='Min'))
werkt prima en retourneert eenDataFrameGroupBy
-object voor verdere verwerking, bijvoorbeeld: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
Echteris de klasse TimeGrouper
niet gedocumenteerd.
Wat is de juiste manier om te groeperen op een tijdsperiode? Hoe kan ik de gegevens groeperen op een minuut EN op de kolom Bron, b.v. groupby([TimeGrouper(freq='Min'), df.Source])
?
Antwoord 1, autoriteit 100%
Je kunt groeperen op elke array/reeks van dezelfde lengte als je DataFrame — zelfs een berekende factor die niet echt een kolom van het DataFrame is. Dus groeperen per minuut kun je doen:
df.groupby(df.index.map(lambda t: t.minute))
Als je per minuut en iets anders wilt groeperen, meng dan het bovenstaande met de kolom die je wilt gebruiken:
df.groupby([df.index.map(lambda t: t.minute), 'Source'])
Persoonlijk vind ik het handig om kolommen aan het DataFrame toe te voegen om sommige van deze berekende dingen op te slaan (bijvoorbeeld een “Minute”-kolom) als ik er vaak op wil groeperen, omdat het de groeperingscode minder uitgebreid maakt.
Of je zou iets als dit kunnen proberen:
df.groupby([df['Source'],pd.TimeGrouper(freq='Min')])
Antwoord 2, autoriteit 35%
Aangezien het oorspronkelijke antwoord nogal oud is en panda’s perioden
een andere oplossing is tegenwoordig:
df.groupby(df.index.to_period('T'))
Bovendien kunt u hersamplen
df.resample('T')
Antwoord 3, autoriteit 20%
pd.TimeGrouper wordt nu afgeschreven. Hier is v1.05-update met behulp van pd.Grouper
df['Date'] = df.index
df.groupby(['Source',pd.Grouper(key = 'Date', freq='30min')])