2016-07-29 21 views
2

Ich habe den folgenden Datenrahmen und ich versuche, einen ganzen Block mit einer Zahl zu beschriften, die darauf basiert, wie viele ähnliche Blöcke bisher basierend auf Klassenspalte gesehen wurden. Der fortlaufende Klassenwert erhält die gleiche Nummer. Wenn derselbe Klassenblock später kommt, wird die Nummer inkrementiert. Wenn ein neuer Klassenblock kommt, wird er auf 1 initialisiert.Zählen von wiederholten Blöcken in Pandas

df = DataFrame(zip(range(10,30), range(20)), columns = ['a','b']) 
df['Class'] = [np.nan, np.nan, np.nan, np.nan, 'a', 'a', 'a', 'a', np.nan, np.nan,'a', 'a', 'a', 'a', 'a', np.nan, np.nan, 'b', 'b','b'] 

    a b Class 
0 10 0 NaN 
1 11 1 NaN 
2 12 2 NaN 
3 13 3 NaN 
4 14 4  a 
5 15 5  a 
6 16 6  a 
7 17 7  a 
8 18 8 NaN 
9 19 9 NaN 
10 20 10  a 
11 21 11  a 
12 22 12  a 
13 23 13  a 
14 24 14  a 
15 25 15 NaN 
16 26 16 NaN 
17 27 17  b 
18 28 18  b 
19 29 19  b 

Beispielausgabe sieht wie folgt aus:

a b Class block_encounter_no 
0 10 0 NaN NaN 
1 11 1 NaN NaN 
2 12 2 NaN NaN 
3 13 3 NaN NaN 
4 14 4 a 1 
5 15 5 a 1 
6 16 6 a 1 
7 17 7 a 1 
8 18 8 NaN NaN 
9 19 9 NaN NaN 
10 20 10 a 2 
11 21 11 a 2 
12 22 12 a 2 
13 23 13 a 2 
14 24 14 a 2 
15 25 15 NaN NaN 
16 26 16 NaN NaN 
17 27 17 b 1 
18 28 18 b 1 
19 29 19 b 1 

Antwort

2

Lösung mit mask:

df['block_encounter_no'] = (df.Class != df.Class.shift()).mask(df.Class.isnull()) 
           .groupby(df.Class).cumsum() 
print (df) 
    a b Class block_encounter_no 
0 10 0 NaN     NaN 
1 11 1 NaN     NaN 
2 12 2 NaN     NaN 
3 13 3 NaN     NaN 
4 14 4  a     1.0 
5 15 5  a     1.0 
6 16 6  a     1.0 
7 17 7  a     1.0 
8 18 8 NaN     NaN 
9 19 9 NaN     NaN 
10 20 10  a     2.0 
11 21 11  a     2.0 
12 22 12  a     2.0 
13 23 13  a     2.0 
14 24 14  a     2.0 
15 25 15 NaN     NaN 
16 26 16 NaN     NaN 
17 27 17  b     1.0 
18 28 18  b     1.0 
19 29 19  b     1.0 
+0

danke. Aber der letzte Block sollte mit 1 beginnen, da der Block 'b' die neue Klasse ist. – learner

+0

Entschuldigung. Jetzt bearbeite ich die Antwort - add groupby nach 'Class', damit die Lösung korrigiert werden kann. – jezrael

0

tun:

df['block_encounter_no'] = \ 
    np.where(df.Class.notnull(), 
      (df.Class.notnull() & (df.Class != df.Class.shift())).cumsum(), 
      np.nan) 

enter image description here

+0

danke. Aber der letzte Block sollte mit 1 beginnen, da der Block 'b' die neue Klasse ist. – learner

Verwandte Themen