我有一个非常大的pandas数据帧/系列,有数百万个元素。 我需要找到时间戳为<的所有元素。比t0。 通常我会做的是:
selected_df = df[df.index < t0]
这需要很长时间。据我所知,当pandas搜索时,它会遍历数据帧的每个元素。但是我知道我的数据帧已经排序,因此我可以在时间戳为&gt;时打破循环。 T0。我假设大熊猫不知道数据框是如何排序的,并搜索所有时间戳。
我试过用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]
这需要比熊猫搜索更长的时间。 我能看到的唯一解决方案就是使用Cython。 任何想法如何在没有C参与的情况下进行排序?
答案 0 :(得分: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
这快了很多倍。
答案 1 :(得分: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
而不是打开每一个元素,并查看时间戳,而是尝试找到&#34;边界&#34;通过将搜索空间缩小到一半来缩小搜索空间。