У вас есть два вопроса.
На ваш первый вопрос отвечают groupby
, shift
и cumsum
:
df.groupby('id').Col_1.apply(lambda x: x.shift().cumsum())
0 NaN
1 0.0
2 1.0
3 2.0
4 2.0
5 NaN
6 0.0
Name: Col_1, dtype: float64
Или, если вы предпочитаете более чистый вывод,
df.groupby('id').Col_1.apply(lambda x: x.shift().cumsum()).fillna(0).astype(int)
0 0
1 0
2 1
3 2
4 2
5 0
6 0
Name: Col_1, dtype: int64
Ваш второй, также похожий, с использованием groupby
, shift
, cummax
и ffill
:
df.Col_2.where(df.Col_1.eq(1)).groupby(df.id).apply(
lambda x: x.shift().cummax().ffill()
)
0 NaN
1 NaN
2 24.0
3 32.0
4 32.0
5 NaN
6 NaN
Name: Col_2, dtype: float64
В обоих случаях основным ингредиентом является groupby
с последующим последующим вызовом смены.Обратите внимание, что эти ответы трудно решить без apply
, поскольку в подгруппах необходимо выполнить несколько операций.
Попробуйте исключить лямбду, определив пользовательскую функцию.Вы сэкономите несколько циклов на больших данных.