2017-08-08 126 views
1

我有像下面日期時間列比較只在大熊貓時間

col1, mydate 
1, 25-DEC-2016 09:15:00 
2, 25-DEC-2016 10:14:00 
3, 25-DEC-2016 10:16:00 
4, 25-DEC-2016 10:18:56 
2, 25-DEC-2016 11:14:00 
2, 25-DEC-2016 10:16:00 

df.info(): mydate 323809 non-null object 

我需要此數據幀,根據時間,像DF具有時間小於十點15分00秒,DF具有時間以下的DF比使用

times=[pd.to_datetime(i) for i in '10:15:00','11:15:00','12:15:00','13:15:00','14:15:00','15:15:00', '15:30:00'] 

然後將我指明MyDate類型時 這需要大量的時間

:15:00

所以創建了段間隔

df['mydate']=df4.mydate.apply(lambda x: pd.to_datetime(x,infer_datetime_format=True).time()) 

上面的命令我認爲可以優化,或者應該有一個更好/更快的方式。

然後,我只是做

for time in times: 
    slice = df[df.mydate<time.time()] 

我的目的只是爲了df.mydate時間['10:15:00','11:15:00','12:15:00','13:15:00','14:15:00','15:15:00', '15:30:00'](但不是日期)比較和簡單的子集DF

以上的工作方式對我很好,但我正在尋找更好的方法。

附加: 有趣的排序指明MyDate是非常快的(儘管我並沒有轉換成指明MyDate山坳爲datetime)使用

df.sort_values(by='mydate') 

這讓我覺得我的子集的方式應該會更快。

指明MyDate關口始終處於25-DEC-2016 09:15:00格式(注意DEC不十二月),我可以使用format='%d-%b-%Y %H:%M:%S'

+0

爲什麼不只是使用lambda函數來獲取時間子字符串,然後只是使用字符串比較會做。我認爲時間轉換會花費時間。縮短轉換時間將會有所幫助。 – White

回答

0

我相信timedelta是對大熊貓更好的工作 - 所以首先split字符串列,選擇時間轉換:

df['mydate'] = pd.to_timedelta(df['mydate'].str.split().str[1]) 
print (df) 
    col1 mydate 
0  1 09:15:00 
1  2 10:14:00 
2  3 10:16:00 
3  4 10:18:56 
4  2 11:14:00 
5  2 10:16:00 

轉換list太:

times=pd.to_timedelta(['10:15:00','11:15:00','12:15:00', 
         '13:15:00','14:15:00','15:15:00', '15:30:00']) 
print (times) 
TimedeltaIndex(['10:15:00', '11:15:00', '12:15:00', '13:15:00', '14:15:00', 
       '15:15:00', '15:30:00'], 
       dtype='timedelta64[ns]', freq=None) 

拉ST創建切片:

for time in times: 
    sl = df[df.mydate<time] 
    print (sl) 
+0

謝謝。作爲額外的疑問,我想知道'df.sort_values(by ='mydate')'如何排序值(不需要任何類型轉換)。這是排序這種方式的好方法嗎? – pythonRcpp

+0

我想是的,'timedelta'工作很好。 – jezrael

0

首先,我建議使用對整個陣列/系列pd.to_datetime,所以這將是:

pd.to_datetime(['10:15:00','11:15:00','12:15:00','13:15:00']).time 

不是

[pd.to_datetime(i).time() for i in ['10:15:00','11:15:00','12:15:00','13:15:00']] 

其次,你對格式是正確的。作爲pd.to_datetime的文件中說,它的速度要快得多(由x5-10次)使用

pd.to_datetime(['25-DEC-2016 09:15:00', '25-DEC-2016 09:15:00'], 
       format='%d-%b-%Y %H:%M:%S') 

不是

pd.to_datetime(['25-DEC-2016 09:15:00', '26-DEC-2016 09:15:00'], 
       infer_datetime_format=True) 

現在考慮您的數據框:

df = pd.DataFrame({'col1': [1, 2, 3, 2], 
        'mydate': ['25-DEC-2016 09:15:00', 
           '25-DEC-2016 11:15:00', 
           '26-DEC-2016 11:15:00', 
           '26-DEC-2016 12:15:00']}) 
>>> 
    col1    mydate 
0  1 25-DEC-2016 09:15:00 
1  2 25-DEC-2016 11:15:00 
2  3 26-DEC-2016 11:15:00 
3  2 26-DEC-2016 12:15:00 

你可以首先將mydate列轉換爲實際的datetime系列:

df['mydate'] = pd.to_datetime(df.mydate, format='%d-%b-%Y %H:%M:%S') 

然後你就可以通過dt存取訪問datetime字段(以及更多):

df.mydate.dt.date 
>>> 
0 2016-12-25 
1 2016-12-25 
2 2016-12-26 
3 2016-12-26 

df.mydate.dt.time 
>>> 
0 09:15:00 
1 11:15:00 
2 11:15:00 
3 12:15:00 

因此,在計算切片時,你可以使用:

for time in times: 
    slice = df[df.mydate.dt.time < time] 
    print(time, slice, sep='\n') 
>>> 
10:15:00 
    col1    mydate 
0  1 2016-12-25 09:15:00 
11:15:00 
    col1    mydate 
0  1 2016-12-25 09:15:00 
12:15:00 
    col1    mydate 
0  1 2016-12-25 09:15:00 
1  2 2016-12-25 11:15:00 
2  3 2016-12-26 11:15:00 
13:15:00 
    col1    mydate 
0  1 2016-12-25 09:15:00 
1  2 2016-12-25 11:15:00 
2  3 2016-12-26 11:15:00 
3  2 2016-12-26 12:15:00 

注意你得到的實際上並不是切片,因爲它們有重疊的記錄,所以你可能想用類似的東西:

for start, end in zip(times, times[1:]): 
    slice = df[(start <= df.mydate.dt.time) & (df.mydate.dt.time <= end)] 

作爲最後一點,您正在嘗試使用for循環完成的任務可以使用來自熊貓的group by操作獲得。你只需要準備一個mytime列,只有與時俱進:

df['mytime'] = df.mydate.dt.time 
groups = df.groupby('mytime') 

for group_key, group_df in groups: 
    print(group_key, group_df, sep='\n') 
>>> 
09:15:00 
    col1    mydate mytime 
0  1 2016-12-25 09:15:00 09:15:00 
11:15:00 
    col1    mydate mytime 
1  2 2016-12-25 11:15:00 11:15:00 
2  3 2016-12-26 11:15:00 11:15:00 
12:15:00 
    col1    mydate mytime 
3  2 2016-12-26 12:15:00 12:15:00 

的好處是,你並不需要在單dataframes操作,但你可以在應用上的每個組相同的操作和聚合同時:

groups.size() 
>>> 
mytime 
09:15:00 1 
11:15:00 2 
12:15:00 1 

groups.sum() 
>>> 
      col1 
mytime   
09:15:00  1 
11:15:00  5 
12:15:00  2