2017-01-02 6 views
5

Betrachten Sie meinen Datenrahmen dfPython Pandas bedingte kumulative Summe

data data_binary sum_data 
    2  1   1 
    5  0   0 
    1  1   1 
    4  1   2 
    3  1   3 
    10  0   0 
    7  0   0 
    3  1   1 

ich die kumulative Summe von data_binary innerhalb von Gruppen von zusammenhängenden 1 Werten berechnet werden soll.

Die erste Gruppe von 1 hatte eine einzige 1 und hat nur eine 1. Die zweite Gruppe von 1 hat jedoch 3 1 und ist [1, 2, 3].

Ich habe versucht, np.where(df['data_binary'] == 1, df['data_binary'].cumsum(), 0) verwenden, aber das gibt

array([1, 0, 2, 3, 4, 0, 0, 5]) 

Welche nicht das, was ich will.

+2

Was haben Sie versucht und was ist Ihre Anforderung? Deine Frage ist nicht klar. Bearbeite es. – MYGz

+0

Ich möchte sum_data mithilfe von Datenspalten berechnen. – GrayHash

+0

immer noch keine Ahnung, was Sie wollen und was Sie versucht haben, funktioniert nicht. – dartdog

Antwort

5

Ich denke, man kann groupby mit DataFrameGroupBy.cumsum von Series, wo unmittelbar neben dem Wert von shift ed Spalte vergleichen, wenn nicht gleich (!=) und dann Gruppen von cumsum erstellen. Zuletzt ersetzen 0 durch Spalte data_binary mit mask:

print (df.data_binary.ne(df.data_binary.shift()).cumsum()) 
0 1 
1 2 
2 3 
3 3 
4 3 
5 4 
6 4 
7 5 
Name: data_binary, dtype: int32 

df['sum_data1'] = df.data_binary.groupby(df.data_binary.ne(df.data_binary.shift()).cumsum()) 
           .cumsum() 
df['sum_data1'] = df['sum_data1'].mask(df.data_binary == 0, 0) 
print (df) 
    data data_binary sum_data sum_data1 
0  2   1   1   1 
1  5   0   0   0 
2  1   1   1   1 
3  4   1   2   2 
4  3   1   3   3 
5 10   0   0   0 
6  7   0   0   0 
7  3   1   1   1 
+0

Sie haben jetzt Außenseiterhut! – piRSquared

9

Sie die kumulative Summe von data_binary und subtrahieren Sie die neueste kumulative Summe, wo data_binary war Null zu nehmen.

b = df.data_binary 
c = b.cumsum() 
c.sub(c.mask(b != 0).ffill(), fill_value=0).astype(int) 

0 1 
1 0 
2 1 
3 2 
4 3 
5 0 
6 0 
7 1 
Name: data_binary, dtype: int64 

Erklärung

Anfang Lassen von ihnen bei jedem Schritt zur Seite schaut

cols = ['data_binary', 'cumulative_sum', 'nan_non_zero', 'forward_fill', 'final_result'] 
print(pd.concat([ 
     b, c, 
     c.mask(b != 0), 
     c.mask(b != 0).ffill(), 
     c.sub(c.mask(b != 0).ffill(), fill_value=0).astype(int) 
    ], axis=1, keys=cols)) 


    data_binary cumulative_sum nan_non_zero forward_fill final_result 
0   1    1   NaN   NaN    1 
1   0    1   1.0   1.0    0 
2   1    2   NaN   1.0    1 
3   1    3   NaN   1.0    2 
4   1    4   NaN   1.0    3 
5   0    4   4.0   4.0    0 
6   0    4   4.0   4.0    0 
7   1    5   NaN   4.0    1 

Das Problem mit cumulative_sum ist, dass die Zeilen, in denen data_binary Null ist, tun Setze die Summe nicht zurück. Und das ist die Motivation für diese Lösung. Wie setzen wir die Summe zurück, wenn data_binary Null ist? Einfach! Ich zerschneide die kumulative Summe, wobei data_binary Null ist und die Werte vorwärts füllt. Wenn ich den Unterschied zwischen dieser und der kumulativen Summe nehme, habe ich die Summe effektiv zurückgesetzt.