如何在Python中用更快的选项替换for循环

时间:2016-08-26 12:37:23

标签: python pandas

我有两个数据框,大约有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循环并适合更长的数据帧?

2 个答案:

答案 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)。