2016-12-02 69 views
0

我有一個需要很長時間才能運行的python程序,很可能是因爲我在使用循環,我希望能夠在一節中使用Pandas或Numpy來獲得一些幫助。加快速度。看起來第一個FOR循環可以用熊貓或numpy進行一點優化。也就是說,我並不是完全熟悉熊貓或numpy的錯綜複雜,以達到這個循環的目的。任何幫助表示讚賞,請讓我知道如果有任何問題,謝謝!優化Python代碼 - 熊貓/ Numpy的使用

df = data below  
df2 = pandas.DataFrame() 

for i in df.index: 
    if df.V[i]>1: 
     for f in range(0,df.V[i]): 
      df2 = df2.append(df.loc[i],ignore_index=True) 
    elif df.V[i]==1: 
     df2 = df2.append(df.loc[i],ignore_index=True) 


df2.V = 1 
df2['Grouper']="" 


bv=10 
y=bv 
x=len(df2) 


for d in range(0,x,y): 
    z = d+y 
    df2['Grouper'][d:z]=d 


df3 = df2.groupby('Grouper').agg({'Date_Time':'first','L1':'last','H':'max','L2':'min','O':'first'}) 
df3 = df3.reset_index(drop=True) 
df3 = df3[['Date_Time','O','H','L1','L2']] 

這是數據的樣本,我這個程序使用(DF):

   Date_Time O  H  L1  L2   V 
0  2016-10-13 17:00:00 50.39 50.39 50.39 50.39  1 
1  2016-10-13 17:00:02 50.39 50.39 50.39 50.39  27 
2  2016-10-13 17:00:04 50.38 50.38 50.38 50.38  1 
3  2016-10-13 17:00:09 50.38 50.38 50.38 50.38  1 
4  2016-10-13 17:00:10 50.38 50.38 50.38 50.38  6 
5  2016-10-13 17:00:14 50.38 50.38 50.38 50.38  19 
6  2016-10-13 17:00:15 50.38 50.38 50.38 50.38  3 
7  2016-10-13 17:00:20 50.37 50.38 50.37 50.38  5 
8  2016-10-13 17:00:21 50.38 50.38 50.38 50.38  2 
9  2016-10-13 17:00:22 50.38 50.38 50.37 50.37  3 
+0

您能否包含原始數據和預期數據?給定的數據框將不起作用,因爲具有兩個具有相同名稱的列(應該不惜一切代價避免)會導致groupby崩潰)。如果你用文字解釋你想要達到的目標,也會有所幫助,因爲有可能嘗試不同的方法。 –

+0

@KenWei我應用了您推薦的更改。目標是通過'V'列來分解數據,所以df中的第2行將在df2中具有27個相同數據的條目。然後,我重新組合df2中的數據以基於'V'列中的條目總和創建桶。基本上試圖創建恆定的音量條。 – BROB1

回答

2

for循環肯定是非常緩慢的:一開始,索引成數據幀是相當昂貴在計算時間方面。 df.V[i]通過鏈接索引還有另一個小的性能損失;如果你做了df.loc[i,'V'],事情會稍微快一點。儘管如此,通過索引遍歷數據框的速度非常緩慢,對於大多數問題通常可以避免(如果您絕對必須的話,df.iterrows()會爲您提供稍微快一點的迭代器)。代碼緩慢的另一個來源是,每次調用.append()方法時都會創建數據幀的副本,這對於大數據集來說很難實現。對於這個例子,我們可以避免做所有這些。

我猜測你有一些按整數索引的時間序列數據;當您的數據按時間索引時,熊貓可以很好地處理這類問題(重新採樣),因此我們將強制時間格式轉換爲數據並使用resample方法。

df['v'] = pd.to_datetime(df.V.cumsum()) # assign times to each datapoint; in this case, nanoseconds after the start of Unix time. 
r = df.set_index('v').resample('10N') # the 'N' stands for nanoseconds 
df3 = r.agg({'Date_Time':'first','L1':'last','H':'max','L2':'min','O':'first'}) 
df3.interpolate(method = 'zero', inplace = True) 
df3.reset_index(drop = True, inplace = True) 
to_fix = df3.index[df3.Date_Time.isnull()] 
for i in to_fix: 
    df3.loc[i,'Date_Time'] = df3.loc[i-1,'Date_Time'] 

一些言論:

  1. 需要,因爲當你有V大是 '穿越' 聚集週期中的插值方法;參數method='zero'告訴 熊貓只是採取它之前的行。但是,對於字符串它不起作用 ,因此您需要手動替換這些;最好的我 可以想到的是一個for循環,希望不會迭代太多次。
  2. inplace = True參數意味着數據被直接修改,而不是創建數據框的修改後的副本,並用它
  3. 新人換舊人的.agg()方法允許你使用你希望聚集的東西不止一個功能,所以如果您想要'min''last'L,則可以傳遞參數{'L':['min','last']}{'L':{'custom_colname1':'min','custom_colname2':'min'}}。結果是,這產生了一個嵌套的列索引,其中最簡單的展平方法是直接修改數據框的.columns屬性(但要小心名稱的順序,因爲字典傳入的方法沒有排序!
+0

我可能沒有正確使用代碼,似乎無法獲得匹配的結果。結果我期望從代碼和示例數據。 'Date_Time OH L1 L2' '0 2016-10-13 17:00:00 50.39 50.39 50.39 50.39' '1 2016-10-13 17:00:02 50.39 50.39 50.39 50.39' '2 2016-10- 13 17:00:02 50.39 50.39 50.38 50.38' '3 2016-10-13 17:00:10 50.38 50.38 50.38 50.38' '4 2016-10-13 17:00:14 50.38 50.38 50.38 50.38' '5 2016-10-13 17:00:14 50.38 50.38 50.37 50.38' '6 2016-10-13 17:00:20 50.37 50.38 50.37 50.37' – BROB1

+0

此鏈接更好地解釋了我正在嘗試執行的操作:http:// help .cqg.com/cqgic/14/Default.htm的#!文件/ constantvolumebarcvb1.htm – BROB1