Получить значение предыдущей строки по группе после выполнения условия - PullRequest
0 голосов
/ 25 мая 2020

У меня следующая проблема. Это мой фрейм данных:

district    curfew_name        active   value    date
  A            np.nan            0       10       1
  A             B1               1       20       4
  A             B1               1       21       6
  C             D1               1       14       8      
  C             D1               1       16       11
  C             D2               1       14       13
  E             F1               0       30       10
  E             F1               1       14       12

Итак, каждая строка - это дата (2-3 дня между каждой строкой), в которой district может иметь активированный комендантский час. Поэтому я хочу знать для каждого комендантского часа, какое значение было в столбце value для этого района в день перед первой активацией указанного комендантского часа. Итак, в этом случае комендантский час B1 активируется в дату 4, поэтому я проверяю предыдущий value для этого района, и это 10. Для комендантского часа D1 Я не знаю, какой предыдущий value для в том районе, поэтому я бы получил nan. Для D2 предыдущим значением является последнее значение D1: 16. Наконец, для F1 мы видим, что оно было объявлено заранее, поэтому мы получаем 0 до того, как оно станет активным. В любом случае значение будет 30. Итак, мой последний Series будет выглядеть так:

curfew_name    previous_value
    B1              10
    D1             np.nan
    D2              16
    F1              30

Итак, я могу получить первое появление каждого комендантского часа следующим образом:

df[df.active.eq(1)].reset_index().groupby('curfew_name').first()['index']

А затем я просто попытался вычесть один, а затем извлеките эти индексы:

idx = df[df.active.eq(1)].reset_index().groupby('curfew_name').first()['index'] - 1

Но для таких случаев, как D1, я получил бы 21, который является значением из другого района. Как бы вы go могли об этом? Я пробовал несколько комбинаций groupby('district'), shift(), eq(), но я все еще не делаю это эффективно.

Спасибо!

Изменить: мой подход на данный момент было бы получить предыдущий индекс, а затем проверить, находится ли строка, связанная с этим индексом, в том же районе, что и исходный индекс, и отфильтровать те, когда это условие выполняется, но я совершенно уверен, что могу сделать что-то лучше.

Ответы [ 2 ]

0 голосов
/ 25 мая 2020

Получив вдохновение из ответа @Quang Hoang и моего первоначального подхода, мне удалось это сделать:

df['previous_value'] = df.groupby('district').value.shift()
idx = df[df.active.eq(1)].reset_index().groupby('curfew_name').first()['index']
previous_values = df[df.index.isin(idx )].set_index('curfew_name').previous_value
0 голосов
/ 25 мая 2020

IIU C:

(df.assign(previous_value=df.groupby('district').value.shift())  # usual groupby.shift
   .drop_duplicates(['district','curfew_name'])                  # drop all duplicates
  [['curfew_name','previous_value']]                             # select the columns of interest
   .dropna(subset=['curfew_name'])                               # ignore curfew with nan values
)

Вывод:

  curfew_name  previous_value
1          B1            10.0
3          D1             NaN
5          D2            16.0
7          F1            30.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...