¿Cómo agrupar DataFrame por un período de tiempo?

Tengo algunos datos de los archivos de registro y me gustaría agrupar las entradas por un minuto:

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 

Probé estas opciones:

  1. df.resample('Min') es un nivel demasiado alto y desea agregarse.
  2. df.groupby(date_range(datetime(2012,1,1,12, 30), freq='Min', periods=4)) falla con la excepción.
  3. df.groupby(TimeGrouper(freq='Min')) funciona bien y devuelve un objeto DataFrameGroupBy para su posterior procesamiento, por ejemplo:

     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 

Sin embargo , la clase TimeGrouper no está documentada.

¿Cuál es la forma correcta de agrupar por un período de tiempo? ¿Cómo puedo agrupar los datos por un minuto Y por la columna Fuente, por ejemplo, groupby([TimeGrouper(freq='Min'), df.Source]) ?

Puede agrupar en cualquier matriz / serie de la misma longitud que su DataFrame, incluso un factor computado que en realidad no es una columna de la DataFrame. Así que para agrupar por minuto puedes hacer:

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

Si desea agrupar por minuto y algo más, simplemente mezcle lo anterior con la columna que desea usar:

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

Personalmente, me parece útil simplemente agregar columnas al DataFrame para almacenar algunas de estas cosas computadas (por ejemplo, una columna de “Minuto”) si quiero agruparlas a menudo, ya que hace que el código de agrupación sea menos detallado.

O podrías probar algo como esto:

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

Como la respuesta original es bastante antigua y los pandas introdujeron períodos , hoy en día una solución diferente es:

 df.groupby(df.index.to_period('T')) 

Además, puede remuestrear

 df.resample('T')