2017-08-08 128 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