2014-04-01 42 views
0

我有以下循環,其中10000循環需要超過9秒。對於我的程序,我必須執行超過1000次這個功能。我需要一些幫助來優化「simu」函數,因爲從現在開始,我的代碼從持續時間開始無法使用。有關信息,日期範圍值僅作爲示例,但可能與其他人非常不同。循環和條件代碼最快的方法(Python + Dataframes)

採取什麼時間大多:

  • df.itertuples([ 'DATES'])
  • 環即使使用迭代
  • 如果條件
  • 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 
+0

可以顯示什麼日期範圍是? – Jeff

+0

是的抱歉!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)]] –

+0

請看這裏:http://pandas.pydata.org/pandas- docs/stable/enhanceperf.html < - 我有一個類似的問題,並通過去Cython我一個大循環從132秒下降到220毫秒。 – Carst

回答

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