2012-06-17 9 views
33

Ich habe einige Daten aus den Log-Dateien und von einer Minute Gruppeneinträge möchten:Wie gruppiere ich DataFrame um einen bestimmten Zeitraum?

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 

Ich habe versucht, diese Optionen:

  1. df.resample('Min') ist zu hoch Ebene und möchte aggregieren.
  2. df.groupby(date_range(datetime(2012,1,1,12, 30), freq='Min', periods=4)) schlägt mit Ausnahme fehl.
  3. df.groupby(TimeGrouper(freq='Min')) funktioniert gut und gibt ein DataFrameGroupBy Objekt für die weitere Verarbeitung, z.B .:

    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 
    

jedoch, die TimeGrouper Klasse nicht dokumentiert ist.

Was ist die richtige Gruppierung nach einem bestimmten Zeitraum? Wie kann ich die Daten um eine Minute UND durch die Quellenspalte, z. groupby([TimeGrouper(freq='Min'), df.Source])?

Antwort

39

Sie können auf jedem Array/jeder Serie mit derselben Länge wie Ihr DataFrame gruppieren --- sogar ein berechneter Faktor, der eigentlich keine Spalte des DataFrames ist. So gruppieren von Minuten können Sie tun:

df.groupby(df.index.map(lambda t: t.minute)) 

Wenn Sie von Minute und etwas anderes zu gruppieren wollen, nur mit der Säule die oben mischen Sie verwenden möchten:

df.groupby([df.index.map(lambda t: t.minute), 'Source']) 

Persönlich finde ich es nützlich, um einfach Spalten zu dem Datenrahmen hinzuzufügen, um einige dieser berechneten Dinge zu speichern (zB eine Spalte "Minute"), wenn ich häufig nach ihnen gruppieren möchte, da dies den Gruppierungscode weniger ausführlich macht.

Oder Sie könnten so etwas wie dies versuchen:

df.groupby([df['Source'],pd.TimeGrouper(freq='Min')]) 
+3

Danke. Ich habe das Ergebnis erhalten, nach dem ich gesucht habe: df.groupby ([df.index.map (lambda t: datetime (t.year, t.month, t.day, t.hour, t.minute)), df.Source, df.Event]). size(). entstapeln (level = 2) – serguei

+2

wie kann ich es auf 30 minuten erweitern? – igaurav

+7

Dieser pd.TimeGrouper kann verwendet werden, um ein Vielfaches von Zeiteinheiten zu gruppieren 'df.groupby (pd.TimeGrouper (freq = '30Min'))' – salomonvh

Verwandte Themen