#python #pandas
#питон #панды
Вопрос:
Я хотел бы посмотреть на результат за время до изменения продукта и после изменения продукта. Вот пример df:
import pandas as pd ids = [1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2] date = ["11/4/2020", "12/5/2020", "01/5/2021", "02/5/2020", "03/5/2020", "04/5/2020", "05/5/2020", "06/5/2020", "07/5/2020", "08/5/2020", "09/5/2020", "01/3/2019", "02/3/2019", "03/3/2019", "04/3/2019", "05/3/2019", "06/3/2019", "07/3/2019", "08/3/2019", "09/3/2019", "10/3/2019"] months = [0,1,2,3,4,0,1,2,3,4,5,0,1,2,3,4,0,1,2,3,4] df = pd.DataFrame({'ids': ids, 'date': date, 'months': months }) df ids date months 0 1 11/4/2020 0 1 1 12/5/2020 1 2 1 01/5/2021 2 3 1 02/5/2020 3 4 1 03/5/2020 4 5 1 04/5/2020 0 6 1 05/5/2020 1 7 1 06/5/2020 2 8 1 07/5/2020 3 9 1 08/5/2020 4 10 1 09/5/2020 5 11 2 01/3/2019 0 12 2 02/3/2019 1 13 2 03/3/2019 2 14 2 04/3/2019 3 15 2 05/3/2019 4 16 2 06/3/2019 0 17 2 07/3/2019 1 18 2 08/3/2019 2 19 2 09/3/2019 3 20 2 10/3/2019 4
Вот каким я хотел бы видеть конечный результат:
ids date months new_col 0 1 11/4/2020 0 -5 1 1 12/5/2020 1 -4 2 1 01/5/2021 2 -3 3 1 02/5/2020 3 -2 4 1 03/5/2020 4 -1 5 1 04/5/2020 0 0 6 1 05/5/2020 1 1 7 1 06/5/2020 2 2 8 1 07/5/2020 3 3 9 1 08/5/2020 4 4 10 1 09/5/2020 5 5 11 2 01/3/2019 0 -5 12 2 02/3/2019 1 -4 13 2 03/3/2019 2 -3 14 2 04/3/2019 3 -2 15 2 05/3/2019 4 -1 16 2 06/3/2019 0 0 17 2 07/3/2019 1 1 18 2 08/3/2019 2 2 19 2 09/3/2019 3 3 20 2 10/3/2019 4 4
Другими словами, я хотел бы добавить столбец, который находит второй экземпляр months = 0 для определенного идентификатора и отсчитывает его в обратном направлении, чтобы я мог просмотреть результаты до этого момента (все отрицательные числа) по сравнению с результатами после этого момента (все положительные числа).
Есть ли простой способ сделать это в панд?
Заранее спасибо
Ответ №1:
Предположим, что в группе 2 и только 2 экземпляра 0, поэтому мне все равно, ids
потому что:
- (id1, первый 0) -gt; отрицательный счетчик,
- (id1, второй 0) -gt; положительный счетчик,
- (id2, первый 0) -gt; отрицательный счетчик,
- (id2, второй 0) -gt; положительное количество и так далее.
Создавайте виртуальные группы, чтобы знать, нужно ли создавать отрицательный или положительный счетчик:
- нечетная группа: отрицательный счетчик
- четная группа: положительный счетчик
df['new_col'] = ( df.assign(new_col=df['months'].eq(0).cumsum()) .groupby('new_col')['new_col'] .apply(lambda x: range(-len(x), 0, 1) if x.name % 2 else range(len(x))) .explode().values )
Выход:
gt;gt;gt; df ids date months new_col 0 1 11/4/2020 0 -5 1 1 12/5/2020 1 -4 2 1 01/5/2021 2 -3 3 1 02/5/2020 3 -2 4 1 03/5/2020 4 -1 5 1 04/5/2020 0 0 6 1 05/5/2020 1 1 7 1 06/5/2020 2 2 8 1 07/5/2020 3 3 9 1 08/5/2020 4 4 10 1 09/5/2020 5 5 11 2 01/3/2019 0 -5 12 2 02/3/2019 1 -4 13 2 03/3/2019 2 -3 14 2 04/3/2019 3 -2 15 2 05/3/2019 4 -1 16 2 06/3/2019 0 0 17 2 07/3/2019 1 1 18 2 08/3/2019 2 2 19 2 09/3/2019 3 3 20 2 10/3/2019 4 4