python pandas dataframe cumsum

¿Cómo contar el número de ocurrencias antes de un valor particular en el marco de datos python?



pandas dataframe (3)

Pasemos a una línea

df.groupby(df.B.iloc[::-1].cumsum()).cumcount(ascending=False).shift(-1).where(df.B<df.C) Out[80]: 0 NaN 1 1.0 2 NaN 3 NaN 4 1.0 5 0.0 6 NaN dtype: float64

Tengo un marco de datos como el siguiente:

A B C 1 1 1 2 0 1 3 0 0 4 1 0 5 0 1 6 0 0 7 1 0

Quiero el número de ocurrencias de ceros de df[''B''] bajo la siguiente condición:

if(df[''B'']<df[''C'']): #count number of zeroes in df[''B''] until it sees 1.

Rendimiento esperado:

A B C output 1 1 1 Nan 2 0 1 1 3 0 0 Nan 4 1 0 Nan 5 0 1 1 6 0 1 0 7 1 0 Nan

No sé cómo formular la parte de conteo. Cualquier ayuda es muy apreciada


Un enfoque de IIUC sería usar un groupby.cumcount personalizado y agregar con groupby.cumcount :

c1 = df.B.lt(df.C) g = df.B.eq(1).cumsum() df[''out''] = c1.groupby(g).cumcount(ascending=False).shift().where(c1).sub(1)

print(df) A B C out 0 1 1 1 NaN 1 2 0 1 1.0 2 3 0 0 NaN 3 4 1 0 NaN 4 5 0 1 1.0 5 6 0 1 0.0 6 7 1 0 NaN


Usando un poco de enmascaramiento y un groupby en tu serie invertida. Esto supone datos binarios (solo 0 y 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

Y un enfoque rápido basado en 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])

Actuación

df = pd.concat([df]*10_000) %timeit chris1(df) 19.3 ms ± 348 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) %timeit yatu(df) 12.8 ms ± 54.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) %timeit zero_until_one(df[''B''], df[''C'']) 2.32 ms ± 31.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)