在已排序的pandas数据框中,按时间戳搜索元素

4

我有一个非常庞大的pandas数据框/系列,它包含数百万个元素。 我需要查找所有时间戳早于t0的元素。 所以通常我会这样做:

selected_df = df[df.index < t0]

这需要很长时间。据我所知,当pandas进行搜索时,它会遍历数据框中的每个元素。然而,我知道我的数据框已经排序,因此只要时间戳> t0,我就可以中断循环。我假设pandas不知道数据框已经排序,并且会搜索所有时间戳。

我尝试使用pandas.Series,但仍然非常缓慢。 我尝试编写自己的循环,例如:

boudery = 0
ticks_time_list = df.index
tsearch = ticks_time_list[0]
while tsearch < t0:
      tsearch = ticks_time_list[boudery]
      boudery += 1      
selected_df = df[:boudery]

这比使用pandas搜索还要耗时更长。 目前我唯一能想到的解决方案是使用Cython。 有什么想法可以在不涉及C的情况下解决这个问题吗?

2个回答

5

即使是在长时间的框架下,对我来说似乎并不需要很长时间:

>>> df = pd.DataFrame({"A": 2, "B": 3}, index=pd.date_range("2001-01-01", freq="1 min", periods=10**7))
>>> len(df)
10000000
>>> %timeit df[df.index < "2001-09-01"]
100 loops, best of 3: 18.5 ms per loop

但是,如果我们真正想要挤出每一滴性能,可以在降到numpy后使用searchsorted方法:

>>> %timeit df.iloc[:df.index.values.searchsorted(np.datetime64("2001-09-01"))]
10000 loops, best of 3: 51.9 µs per loop
>>> df[df.index < "2001-09-01"].equals(df.iloc[:df.index.values.searchsorted(np.datetime64("2001-09-01"))])
True

这个功能比以前快了很多倍。


非常感谢。这样会更快。有趣的部分在于pandas绝对不是在盲目搜索,因为如果您将“搜索时间”(在本例中为“2001-09-01”)更改为较晚的日期,它会花费更长时间。 - mm441

0

(我对Pandas不是很熟悉,但这描述了一个非常通用的想法 - 你应该能够应用它。如果必要,可以调整Pandas特定的函数。) 您可以尝试使用更高效的搜索。目前,您正在使用线性搜索,遍历所有元素。相反,尝试这个:

ticks_time_list=df.index
tsearch_min = 0
tsearch_max = len(ticks_time_list)-1 #I'm not sure on whether this works on a pandas dataset
while True:
    tsearch_middle = int((tsearch_max-tsearch_min)/2)
    if ticks_time_list[tsearch_middle] < t0:
        tsearch_min = tsearch_middle
    else:
        tsearch_max = tsearch_middle
    if tsearch_max == tsearch_min:
        break
# tsearch_max == tsearch_min and is the value of the index you are looking for

不必打开每个单独的元素并查看时间戳,它会尝试通过将搜索空间一分为二来寻找“边界”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接