2015-11-06 64 views
2

功能近日,我從SAS轉換到Python大熊貓。我的一個問題是大熊貓在SAS中有一個類似於保留的功能,以便我可以動態地引用最後一條記錄。在下面的代碼中,我必須手動循環每一行並引用最後一條記錄。與類似的SAS程序相比,它似乎很慢。無論如何,這使得熊貓更有效率嗎?謝謝。保留在python

import pandas as pd 
import numpy as np 

df = pd.DataFrame({'A': [1, 1, 1, 1], 'B': [0, 0, 1, 0]}) 
df['C'] = np.nan 
df['lag_C'] = np.nan 
for row in df.index: 
    if row == df.head(1).index: 
     df.loc[row, 'C'] = (df.loc[row, 'A'] == 0) + 0 
    else: 
     if (df.loc[row, 'B'] == 1): 
      df.loc[row, 'C'] = 1 
     elif (df.loc[row, 'lag_C'] == 0): 
      df.loc[row, 'C'] = 0 
     elif (df.loc[row, 'lag_C'] != 0): 
      df.loc[row, 'C'] = df.loc[row, 'lag_C'] + 1 
    if row != df.tail(1).index: 
     df.loc[row +1, 'lag_C'] = df.loc[row, 'C'] 
+0

您應該在cython/numba中進行矢量化或編寫。國際海事組織你的代碼是很難推理,但我懷疑有一個可讀/高效的解決方案... –

+0

你可以簡單地說你想達到什麼,即什麼是預期的結果? – miraculixx

+0

如果我幫你,你可以投票並[接受](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)答案(S)。 [更多信息](http://stackoverflow.com/tour) – jezrael

回答

0

非常複雜的算法,但我儘量量化的方法。
如果我的理解是,有可能使用累計總和如使用this question。最後一列lag_C被移動列C

但是我的算法不能在df的第一行中使用,因爲只有這些行從列A的第一個值開始計數,有時列B。所以我創建了D列,其中有顯着的行,後者是複製到輸出列C,如果條件是True

我改變輸入數據和第一測試問題的行。我嘗試測試列B的前3行的所有三種可能性與列的第一行A

我的輸入條件是:
AB1O。列Clag_C是僅有NaN的幫助列。

import pandas as pd 
import numpy as np 

df = pd.DataFrame({'A': [1,1,1,1,1,0,0,1,1,0,0], 'B': [0,0,1,1,0,0,0,1,0,1,0]}) 
df1 = pd.DataFrame({'A': [1,1,1,1,1,0,0,1,1,0,0], 'B': [0,0,1,1,0,0,0,1,0,1,0]}) 

#cumulative sum of column B 
df1['C'] = df1['B'].cumsum() 
df1['lag_C'] = 1 
#first 'group' with min value is problematic, copy to column D for latter use 
df1.loc[df1['C'] == df1['C'].min() ,'D'] = df1['B'] 
#cumulative sums of groups to column C 
df1['C']= df1.groupby(['C'])['lag_C'].cumsum() 
#correct problematic states in column C, use value from D 
if (df1['A'].loc[0] == 1): 
    df1.loc[df1['D'].notnull() ,'C'] = df1['D'] 
if ((df1['A'].loc[0] == 1) & (df1['B'].loc[0] == 1)): 
    df1.loc[df1['D'].notnull() ,'C'] = 0 
del df1['D'] 
#shifted column lag_C from column C 
df1['lag_C'] = df1['C'].shift(1) 
print df1 
# A B C lag_C 
#0 1 0 0 NaN 
#1 1 0 0  0 
#2 1 1 1  0 
#3 1 1 1  1 
#4 1 0 2  1 
#5 0 0 3  2 
#6 0 0 4  3 
#7 1 1 1  4 
#8 1 0 2  1 
#9 0 1 1  2 
#10 0 0 2  1 
+0

非常感謝jezrael。你的邏輯矢量化方法肯定能夠提高速度。後續問題是,如果邏輯變得如此複雜,因此幾乎不可能使用矢量化計算,那麼最有效的方法是什麼?謝謝。 – towin

+0

數據幀有多大?算法有多複雜 - 可以使用numpy的一些函數嗎?是否只使用基本的數學運算(+ - ×÷)?我認爲這取決於這個因素。 – jezrael

+0

現在我只是在做一些簡單的翻譯。我並沒有深入研究背後的邏輯。在進入這一步之前,可能會在其他地方將邏輯簡化。謝謝你的回答。我投了你的答案,它會在我達到15的聲望時出現。 – towin