Группировка с агрегацией по нескольким условиям

Столкнулся с проблемой - нужно посчитать количество строк, удовлетворяющих условиям:

  • в каждом модуле студент выполняет несколько заданий
  • нужно посчитать колличество студентовы, выполнивших последнее задание

Выполненное задание - статус 'done'

Сделал через цикл, но на 50 тыс строк работает нереально долго. Подскажите, есть ли способ сделать группировку с аггрегацией, в которая проверять статус последней строки для каждого модуля, каждого курса, каждого студента и учитывать 1 если статус done и 0 если статус fail (или не учитывать)

Пример датасета:

df = pd.DataFrame({'title':['Курс 1','Курс 1','Курс 1','Курс 1',
                           'Курс 1','Курс 1','Курс 1','Курс 1'],
                    'module_number':['Модуль 1','Модуль 1','Модуль 1', 'Модуль 1',
                                    'Модуль 2','Модуль 2','Модуль 2', 'Модуль 2'],
                   'student_id':['47','47','47', '47',
                                    '47','47','47', '47'],
                    'status':['done','done','done','fail',
                                'done','done','done', 'done']})

Пример результата:

result = pd.DataFrame({'title':['Курс 1','Курс 1'],
                    'module_number':['Модуль 1','Модуль 2'],
                   'count':['0','1']})

Ответы (1 шт):

Автор решения: MaxU
res = (df
      .groupby(["title", "module_number", "student_id"]) 
      ["status"]
      .last()
      .eq("done")
      .groupby(level=[0,1])
      .sum()
      .dropna()
      .astype("int")
      .reset_index())

In [75]: res
Out[75]:
    title module_number  status
0  Курс 1      Модуль 1       0
1  Курс 1      Модуль 2       1
→ Ссылка