我有两个数据框,大约有10 000行。它们与下面的a和b类似,但行数更多。
a
Out[9]:
end start
0 4.0 3
1 5.5 5
2 7.5 7
3 9.5 9
4 11.5 11
5 15.0 14
6 18.0 17
7 21.0 20
8 26.0 25
9 31.0 30
b
Out[10]:
status
moment
8.0 o
10.0 o
14.5 o
16.0 o
19.0 o
27.0 o
28.0 o
30.5 o
35.0 o
40.0 o
50.0 o
我必须在数据帧b中找到属于结束和数据帧a之间的所有时刻。
我开发了for循环,它适用于小型数据帧。
for r in a.index:
for k in b.index:
if a.ix[r,'start'] <k and k <a.ix[r,'end']:
b.ix[k,'status']='m' # replaces m to o if moment is in between start and end
下面你可以看到for循环如何取代o - &gt;当时刻在开始和结束之间时。
n [12]: b
Out[12]:
status
moment
8.0 o
10.0 o
14.5 m
16.0 o
19.0 o
27.0 o
28.0 o
30.5 m
35.0 o
40.0 o
50.0 o
当我尝试将其用于庞大的数据帧(数据帧中超过10 000行)时,它无法在合理的时间内获得结果。
您是否有任何想法如何更快地阐述我的for循环并适合更长的数据帧?
答案 0 :(得分:1)
这是一个没有for
循环的选项,它不会避免矢量扫描,而是进行矢量化:
b[b.index.map(lambda m: ((m > a.start) & (m < a.end)).any())] = "m"
b
# status
# moment
# 8.0 o
# 10.0 o
# 14.5 m
# 16.0 o
# 19.0 o
# 27.0 o
# 28.0 o
# 30.5 m
# 35.0 o
# 40.0 o
# 50.0 o
答案 1 :(得分:0)
您的解决方案在运行时间为O(n^2)
。据我所知,所有的数据帧都是排序的,如果是整个DF
的情况,你可以做一个分而治之的方法来使它成为O(nlogn)
。但是编码并不容易,你必须查阅它,理解D&amp; C方法并将其写为递归函数。我认为你可以为这个问题创建一个所谓的BinarySearch
算法,每个元素都是O(logn),所以O(nlogn)。
如果我错了并且DF
没有排序,但你必须多次进行这种搜索,我建议先对它进行排序。排序也可以在D&amp; C中完成,通常称为MergeSort
及其O(nlogn)。