Фильтрация DataFrame по свойствам его групп - PullRequest
0 голосов
/ 01 мая 2018

Допустим, у нас есть журналы отслеживания проблем, и мы хотим выяснить владельцев проблем (ребята, которые выполнили наибольшее количество времени для проблемы)

  1. Пользователь может регистрировать время несколько раз для одной и той же проблемы
  2. Если 2 пользователя одновременно регистрируются, то оба они являются владельцами

Итак, у нас есть пример данных:

df = pd.DataFrame([
        [1, 10, 'John'],
        [1, 20, 'John'],
        [1, 30, 'Tom'],
        [1, 10, 'Bob'],
        [2, 25, 'John'],
        [2, 15, 'Bob']], columns = ['IssueKey','TimeSpent','User'])

В качестве вывода мы хотим что-то вроде этого:

issues_owners = pd.DataFrame([
        [1, 30, 'John'],
        [1, 30, 'Tom'],
        [2, 25, 'John']], columns = ['IssueKey','TimeSpent','User'])
  1. И Джон, и Том являются владельцами проблемы 1, поскольку они оба потратили на нее 30 минут.
  2. Джон фактически работал над выпуском 1 в 2 отдельных дня
  3. Джон также является владельцем выпуска 2
  4. Боб ленив и не имеет проблем:)

То, что я придумал, кажется довольно отвратительным (я относительно новичок в Python):

df = df.groupby(['IssueKey', 'User']).sum().reset_index()
maxTimesPerIssue = df.groupby('IssueKey')['TimeSpent'].max().reset_index()
maxTimesPerIssue = dict(zip(maxTimesPerIssue['IssueKey'], maxTimesPerIssue['TimeSpent']))
df['MaxTimePerIssue'] = [maxTimesPerIssue[key] for key in df['IssueKey']]
df = df[df.MaxTimePerIssue == df.TimeSpent]
df = df.drop(columns=['MaxTimePerIssue'])   

Что мне не нравится в моем коде Python:

  1. maxTimesPerIssue появляется в середине обработки df, нарушая мыслительный процесс (или конвейер)
  2. Создание maxTimesPerIssue само по себе немного грязно
  3. Добавление MaxTimePerIssue df
  4. Это определенно менее очевидно, чем версия C #, из-за использования множества низкоуровневых вещей, таких как: reset_index(), list(), dict(), списки, отбрасывание столбцов

Кто-нибудь может мне помочь убрать его?

1 Ответ

0 голосов
/ 01 мая 2018

Что-то вроде groupby будет работать для ваших данных:

i = df.groupby(['IssueKey', 'User']).TimeSpent.sum()
j = i.groupby(level=0).transform('max')

i[i == j].reset_index()

   IssueKey  User  TimeSpent
0         1  John         30
1         1   Tom         30
2         2  John         25
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...