2012-06-17 132 views
33

我从日志文件中的一些数据,并希望组条目由一分钟:如何将DataFrame分组一段时间?

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 

我尝试这些选项:

  1. df.resample('Min')过高级别并想要聚合。
  2. df.groupby(date_range(datetime(2012,1,1,12, 30), freq='Min', periods=4))失败,异常。
  3. df.groupby(TimeGrouper(freq='Min'))工作正常,并返回一个DataFrameGroupBy对象进行进一步的处理,例如:

    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 
    

然而,在TimeGrouper类没有记载。

按一段时间分组的正确方法是什么?如何将数据分组一分钟和“源”列进行分组,例如groupby([TimeGrouper(freq='Min'), df.Source])

回答

39

您可以将任何数组/序列与您的DataFrame长度相同---即使是一个计算因子,它实际上并不是DataFrame的一列。因此,要通过分小组,你可以这样做:

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

如果你想按分钟和别的东西,只是混合上面列要使用:

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

我个人觉得如果我想经常对它们进行分组,那么这对于向DataFrame添加列来存储某些计算出来的内容(例如,“分钟”列)非常有用,因为它会使分组代码变得更加冗长。

或者你可以尝试这样的事:

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

谢谢。 df.groupby([df.index.map(lambda t:datetime(t.year,t.month,t.day,t.hour,t.minute)),我得到了我想要的结果: df.Source,df.Event])。size()。unstack(level = 2) – serguei

+2

我怎样才能把它延长到30分钟? – igaurav

+7

这个pd.TimeGrouper可以用多个时间单位进行分组'df.groupby(pd.TimeGrouper(freq ='30Min'))' – salomonvh