循环和条件代码的最快方法(Python + Dataframes)

时间:2014-04-01 21:24:25

标签: python optimization pandas

我有以下循环,10 000次循环需要9秒以上。对于我的程序,我必须执行超过1000次此功能。我需要一些帮助来优化“simu”功能,因为从现在起我的代码从持续时间开始就无法使用。对于info,daterange值仅作为示例,但可以与其他值非常不同。

主要花费时间:

  • df.itertuples([ 'DATES'])
  • 循环甚至使用迭代器
  • if condition
  • f.index.get_loc拥有日期的位置

有人知道如何优化此代码吗?

def simu(nbprod, df, daterange):


    timer = time.time()
    mat = np.zeros((len(df), nbprod))

    iterator = ((i,j) for j in xrange(len(daterange)) for i in df.itertuples(['DATES']))

    for (i,j) in iterator:
        thedate = i[0]
        if (thedate >= daterange[j][0]) and (thedate <= daterange[j][1]):
            mat[df.index.get_loc(i[0])][j] = 1

    print time.time() - timer

    return mat


new_index = pd.date_range(start=pd.datetime(2014,1,1), periods=24*10000, freq='H')
df = pd.DataFrame(np.random.randn(len(new_index)), new_index)
df.index.name = 'DATES'

daterange = [[pd.datetime(2014,1,3), pd.datetime(2014,1,7)], [pd.datetime(2015,6,3), pd.datetime(2017,1,7)], [pd.datetime(2017,1,3), pd.datetime(2020,1,7)]]

### for 1 time
>>> simu(len(daterange), df, daterange)
9.43400001526

### for 3 times more
>>> simu(len(daterange)*3, df, daterange*3)
30.6919999123

>>> simu(len(daterange)*10, df, daterange*10)
92.2009999752

1 个答案:

答案 0 :(得分:1)

这会返回一个帧,无论如何都是恕我直言(如果你想要底层的话) 数据,只是df.values。这将与日期范围的长度成线性比例。

def simu2(df, daterange):

    mat = pd.DataFrame(0,index=df.index,columns=range(len(daterange)))
    for j, (d1,d2) in enumerate(daterange):
        result = df[(df.index>=d1)&(df.index<=d2)]
        mat.loc[result.index,j] = 1

    return mat


In [7]: result1 = simu2(df, daterange)

In [10]: result2 = simu(len(daterange), df, daterange)
5.7844748497

In [11]: (result1.values==result2).all()
Out[11]: True

In [12]: %timeit simu2(df, daterange)
10 loops, best of 3: 162 ms per loop