如果性能很重要,最好不要使用groupby 连续计数Trues:
a = df['colA'].notnull()
b = a.cumsum()
df['Sequence'] = (b-b.mask(a).add(1).ffill().fillna(0).astype(int)).where(a, 0)
print (df)
colA Sequence
0 NaN 0
1 True 0
2 True 1
3 True 2
4 True 3
5 NaN 0
6 True 0
7 NaN 0
8 NaN 0
9 True 0
10 True 1
11 True 2
12 True 3
13 True 4
解释:
df = pd.DataFrame({'colA':[np.nan,True,True,True,True,np.nan,
True,np.nan,np.nan,True,True,True,True,True]})
a = df['colA'].notnull()
#cumulative sum, Trues are processes like 1
b = a.cumsum()
#replace Trues from a to NaNs
c = b.mask(a)
#add 1 for count from 0
d = b.mask(a).add(1)
#forward fill NaNs, replace possible first NaNs to 0 and cast to int
e = b.mask(a).add(1).ffill().fillna(0).astype(int)
#substract b for counts
f = b-b.mask(a).add(1).ffill().fillna(0).astype(int)
#replace -1 to 0 by mask a
g = (b-b.mask(a).add(1).ffill().fillna(0).astype(int)).where(a, 0)
#all together
df = pd.concat([a,b,c,d,e,f,g], axis=1, keys=list('abcdefg'))
print (df)
a b c d e f g
0 False 0 0.0 1.0 1 -1 0
1 True 1 NaN NaN 1 0 0
2 True 2 NaN NaN 1 1 1
3 True 3 NaN NaN 1 2 2
4 True 4 NaN NaN 1 3 3
5 False 4 4.0 5.0 5 -1 0
6 True 5 NaN NaN 5 0 0
7 False 5 5.0 6.0 6 -1 0
8 False 5 5.0 6.0 6 -1 0
9 True 6 NaN NaN 6 0 0
10 True 7 NaN NaN 6 1 1
11 True 8 NaN NaN 6 2 2
12 True 9 NaN NaN 6 3 3
13 True 10 NaN NaN 6 4 4