Как агрегировать накопительный список во фрейме Pandas? - PullRequest
2 голосов
/ 13 июля 2020

У меня есть Pandas фрейм данных, подобный приведенному ниже.

    +--------+-------------------+
    | worker |  day  |    tasks  |
    +--------+-------------------+
    |   A    |   2   | 'read'    |
    |   A    |   9   | 'write'   |
    |   B    |   1   | 'read'    |
    |   B    |   2   | 'write'   |
    |   B    |   4   | 'execute' |
    +--------+-------------------+

Мне нужно сгруппировать фрейм данных по [col_1, day] и получить общий список задач. например, если работник 'A' имеет задачу 'чтение' во 2-й день, тогда задачи для 9-го дня должны быть ['читать', 'писать'] список.

Требуемый фрейм данных выглядит так:

    +--------+-------------------------------------+
    | worker |  day  |          aggregation        |
    +--------+-------------------------------------+
    |   A    |   2   | ['read']                    |
    |   A    |   9   | ['read', 'write']           |
    |   B    |   1   | ['read']                    |
    |   B    |   2   | ['read', 'write']           |
    |   B    |   4   | ['read', 'write', 'execute']|
    +--------+-------------------------------------+

Я пытался использовать cumsum

df = df.groupby(['worker', 'day'])['tasks'].apply(list).reset_index(name='aggregation').cumsum()

Но он собирает накопление для всех столбцов, а не внутри групп для определенного столбца.

1 Ответ

3 голосов
/ 13 июля 2020

Один простой метод (хотя и не идеальный с точки зрения производительности - опять же, вы сохраняете списки в столбцах, поэтому ваш пробег будет отличаться) - это выполнить groupby и cumsum со списками.

df['tasks'].map(lambda x: [x]).groupby(df['worker']).apply(pd.Series.cumsum) 

0                    [read]
1             [read, write]
2                    [read]
3             [read, write]
4    [read, write, execute]
Name: tasks, dtype: object

Или, очень похоже,

(df.assign(tasks=df['tasks'].map(lambda x: [x]))
   .groupby('worker')['tasks']
   .apply(pd.Series.cumsum))

0                    [read]
1             [read, write]
2                    [read]
3             [read, write]
4    [read, write, execute]
Name: tasks, dtype: object

Поскольку вы накапливаете объекты (а не числовые c данные), нам нужно применить pd.Series.cumsum вместо вызова cythonized GroupBy.cumsum, который подавляет в списках python.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...