【问题标题】:Fast selection of a time interval in a pandas DataFrame/Series在 pandas DataFrame/Series 中快速选择时间间隔
【发布时间】:2014-02-26 00:50:22
【问题描述】:

我的问题是我想过滤 DataFrame 以仅包含间隔 [start, end) 内的时间。如果不关心这一天,我只想过滤每天的开始和结束时间。我有一个解决方案,但它很慢。所以我的问题是是否有更快的方法来进行基于时间的过滤。

例子

import pandas as pd
import time


index=pd.date_range(start='2012-11-05 01:00:00', end='2012-11-05 23:00:00', freq='1S').tz_localize('UTC')
df=pd.DataFrame(range(len(index)), index=index, columns=['Number'])

# select from 1 to 2 am, include day
now=time.time()
df2=df.ix['2012-11-05 01:00:00':'2012-11-05 02:00:00']
print 'Took %s seconds' %(time.time()-now) #0.0368609428406

# select from 1 to 2 am, for every day
now=time.time()
selector=(df.index.hour>=1) & (df.index.hour<2)
df3=df[selector]
print 'Took %s seconds' %(time.time()-now) #Took  0.0699911117554

如您所见,如果我删除日期(第二种情况),它几乎需要两倍的时间。如果我有许多不同的日子,例如从 11 月 5 日到 7 日,计算时间会迅速增加:

index=pd.date_range(start='2012-11-05 01:00:00', end='2012-11-07 23:00:00', freq='1S').tz_localize('UTC')

那么,总而言之,有没有一种更快的方法来按一天中的时间进行过滤,跨越多天?

谢谢

【问题讨论】:

    标签: python indexing pandas


    【解决方案1】:

    你需要between_time方法。

    In [14]: %timeit df.between_time(start_time='01:00', end_time='02:00')
    100 loops, best of 3: 10.2 ms per loop
    
    In [15]: %timeit selector=(df.index.hour>=1) & (df.index.hour<2); df[selector]
    100 loops, best of 3: 18.2 ms per loop
    

    我以 11 月 5 日至 7 日为索引进行了这些测试。

    文档

    定义:df.between_time(self, start_time, end_time, include_start=True, include_end=True) 文档字符串: 选择一天中特定时间之间的值(例如,上午 9:00-9:30) 参数 ---------- start_time : datetime.time 或字符串 end_time : datetime.time 或字符串 include_start : 布尔值,默认为 True include_end : 布尔值,默认 True 退货 -------- values_between_time : 调用者的类型

    【讨论】:

    • 您是否愿意做一个 PR 以在 timeseries.rst 中添加一小部分用于这样的用途?
    • Thx,顺便说一下,是否有类似的选择天间隔,例如所有时间都属于指定的一组日期?我当然可以按 index=(df.index.date==a_date) 过滤,但结果非常慢...
    • @Jeff:目前有点忙,不能很快提交 PR。此外,正在使用 0.12 进行项目;所以需要一些时间来开发,直到确保升级时一切正常。您对上述评论有答案吗?between_date 之类的东西?
    • df.query("index &gt;= start_date &amp; index &lt;= end_date") 应该可以工作(开始/结束日期可以是字符串或时间戳/日期时间)
    • 查询方法在时区方面存在一些问题,例如我使用 tz_convert 转换为“Europe/Berlin”,但查询的行为就像时间是 UTC(这是该系列的原始时间,由 tz_localize 强加)。结果是时间过滤的时间序列从凌晨 1 点(UTC 时间上午 0 点)开始,而不是 0 点(前一天 UTC 时间下午 23 点),所以过滤的基础是 UTC 时间,即使我转换为 UTC+1 小时...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    • 2017-06-04
    • 2014-02-17
    • 2015-08-20
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    相关资源
    最近更新 更多