2017-02-22 90 views
5

由於DF來計算大熊貓條紋Python的方式數據幀

df = pd.DataFrame([[1, 5, 2, 8, 2], [2, 4, 4, 20, 2], [3, 3, 1, 20, 2], [4, 2, 2, 1, 3], [5, 1, 4, -5, -4], [1, 5, 2, 2, -20], 
       [2, 4, 4, 3, -8], [3, 3, 1, -1, -1], [4, 2, 2, 0, 12], [5, 1, 4, 20, -2]], 
      columns=['A', 'B', 'C', 'D', 'E'], index=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) 

基於this answer,我創建了一個函數來計算條紋(上,下)。

def streaks(df, column): 
    #Create sign column 
    df['sign'] = 0 
    df.loc[df[column] > 0, 'sign'] = 1 
    df.loc[df[column] < 0, 'sign'] = 0 
    # Downstreak 
    df['d_streak2'] = (df['sign'] == 0).cumsum() 
    df['cumsum'] = np.nan 
    df.loc[df['sign'] == 1, 'cumsum'] = df['d_streak2'] 
    df['cumsum'] = df['cumsum'].fillna(method='ffill') 
    df['cumsum'] = df['cumsum'].fillna(0) 
    df['d_streak'] = df['d_streak2'] - df['cumsum'] 
    df.drop(['d_streak2', 'cumsum'], axis=1, inplace=True) 
    # Upstreak 
    df['u_streak2'] = (df['sign'] == 1).cumsum() 
    df['cumsum'] = np.nan 
    df.loc[df['sign'] == 0, 'cumsum'] = df['u_streak2'] 
    df['cumsum'] = df['cumsum'].fillna(method='ffill') 
    df['cumsum'] = df['cumsum'].fillna(0) 
    df['u_streak'] = df['u_streak2'] - df['cumsum'] 
    df.drop(['u_streak2', 'cumsum'], axis=1, inplace=True) 
    del df['sign'] 
    return df 

該功能運行良好,但是很長。我敢肯定,寫這篇文章有更好的方法。我嘗試了其他答案,但效果不佳。

這是所需的輸出

streaks(df, 'E') 


    A B C D  E d_streak u_streak 
1 1 5 2 8  2   0.0 1.0 
2 2 4 4 20  2   0.0 2.0 
3 3 3 1 20  2   0.0 3.0 
4 4 2 2 1  3   0.0 4.0 
5 5 1 4 -5 -4   1.0 0.0 
6 1 5 2 2 -20   2.0 0.0 
7 2 4 4 3 -8   3.0 0.0 
8 3 3 1 -1 -1   4.0 0.0 
9 4 2 2 0 12   0.0 1.0 
10 5 1 4 20 -2   1.0 0.0 
+0

你能解釋一下這個實現嗎? – Divakar

+0

@Divakar該函數計算> 0和<0的值序列,並保持運行總數的積分,一旦序列結束,它將重置。 – hernanavella

+0

如果有'value == 0'會怎麼樣? – Divakar

回答

6

你可以簡化函數,如下所示:

def streaks(df, col): 
    sign = np.sign(df[col]) 
    s = sign.groupby((sign!=sign.shift()).cumsum()).cumsum() 
    return df.assign(u_streak=s.where(s>0, 0.0), d_streak=s.where(s<0, 0.0).abs()) 

使用它:

streaks(df, 'E') 

enter image description here


首先,使用np.sign來計算所考慮列中存在的每個單元格的符號。這些將+1分配給正數,將-1分配給負數。

接下來,使用sign!=sign.shift()來標識相鄰值的集合(比較當前單元格和下一個單元格),並將其用於分組過程中的累計總和。

執行groupby讓這些作爲關鍵/條件,並再次取得跨子組元素的累計和。

最後,將計算得到的cumsum的值分別計算爲ustreak和負計算值(取其模數後的絕對值)爲dstreak