【问题标题】:Quick way of matching date range to indices in Python list of dates将日期范围与 Python 日期列表中的索引匹配的快速方法
【发布时间】:2013-11-14 10:30:47
【问题描述】:

我需要选择不超过interval 天之前date1 的最早日期的索引(索引i1)。我有一个排序列表dates,这是我正在尝试做的事情的 sn-p:

for i1 in mylist:
    date1 = dates[i1]
    i0 = sum(1 for d in dates if date1 - d > timedelta(days = interval))
    # do some other stuff with this

我找到i0 的那行似乎是这个循环的瓶颈,因为如果我将它更改为i0 = max(0, i1 - 30)(它只是忽略丢失的日期),它的工作速度大约快100 倍。

有没有办法加快速度?我觉得应该有一种方法可以利用列表已排序这一事实,并避免进行所有比较。


PS:我的第一次尝试是:

i0 = len([d for d in dates if date1 - d > timedelta(days = interval)])

甚至更慢。

【问题讨论】:

  • dates 已经订购了吗?与此相关的是,i0 是按顺序排列的第一个索引还是按时间排列的第一个索引?
  • 你可以试试二分查找:i = bisect.bisect_left(dates, dates[i1]-timedelta(days=interval))
  • 要尝试的另一件事——在"searching sorted lists" 上的bisect 模块配方之外——将使用类似两指针滑动窗口的方法。循环遍历每个日期,并让滞后索引递增,直到滞后日期加上间隔 >= 日期。
  • 日期已排序,是的。 i0 是距离date1interval 天内的第一个日期。
  • @J.F.Sebastian 这确实有效并产生了所需的加速。请把它变成一个答案,我会接受它。

标签: python list datetime python-2.7


【解决方案1】:

我需要选择不超过 date1 之前 interval 天的最早日期的索引(索引为 i1)。我有一个排序列表dates

使用二分查找(O(log n)时间复杂度):

import bisect

i = bisect.bisect_left(dates, dates[i1]-timedelta(days=interval))

释义bisect's documentation:返回值i 使得切片dates[:i] 中的所有日期超过 (>)interval 早于date[i1] 天,并且dates[i:] 切片中的所有日期小于或正好 (<=) interval 早于dates[i1] 天。

【讨论】:

    猜你喜欢
    • 2016-01-14
    • 2017-10-12
    • 1970-01-01
    • 1970-01-01
    • 2015-11-08
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多