Создайте новый столбец, который ведет обратный отсчет с определенной точки

#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