使用掩码和对反转后的序列进行分组。这假设二进制数据(仅为0和1)。
m = df['B'][::-1].eq(0)
d = m.groupby(m.ne(m.shift()).cumsum()).cumsum().sub(1)
d[::-1].where(df['B'] < df['C'])
0 NaN
1 1.0
2 NaN
3 NaN
4 1.0
5 0.0
6 NaN
Name: B, dtype: float64
并采用基于numpy
的快速方法
def zero_until_one(a, b):
n = a.shape[0]
x = np.flatnonzero(a < b)
y = np.flatnonzero(a == 1)
d = np.searchsorted(y, x)
r = y[d] - x - 1
out = np.full(n, np.nan)
out[x] = r
return out
zero_until_one(df['B'], df['C'])
array([nan, 1., nan, nan, 1., 0., nan])
性能
df = pd.concat([df]*10_000)
19.3 ms ± 348 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
12.8 ms ± 54.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.32 ms ± 31.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)