2012-06-17 131 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