Суммируйте данные по нескольким строкам во фрейме данных pandas. - PullRequest
0 голосов
/ 29 октября 2019

У меня есть фрейм данных, который принимает эту форму:

import pandas as pd
dict = {'id':["1001", "1001", "1001", "1002", "1002", "1002", "1003", "1003", "1003"], 
    'food': ["apple", "ham", "egg", "apple", "pear", "cherry", "cheese", "milk", "cereal"], 
    'fruit':[1, 0, 0, 1, 1, 1, 0, 0, 0],
    'score':[1, 3, 1, 1, 1, 1, 2, 2, 3]} 
df = pd.DataFrame(dict) 

    id      food    fruit   score
0   1001    apple   1       1
1   1001    ham     0       0
2   1001    egg     0       0
3   1002    apple   1       1
4   1002    pear    1       2
5   1002    cherry  1       3
6   1003    cheese  0       0
7   1003    cherry  1       3
8   1003    cheese  0       0

Я хотел бы создать новый фрейм данных, который имеет одну строку для одного участника (т. Е. Тот же идентификатор), а затем столбцы для пользовательскихСводка данных, например:

  • количество уникальных продуктов
  • количество фруктов
  • общее количество
  • и т. д.

Пример вывода:

      id    unique  fruits  score
0   1001    3       1       1
1   1002    3       3       6
2   1003    2       1       3

Я мог бы создать новый пустой фрейм данных, а затем перебрать уникальные идентификаторы в старом фрейме данных, используя логическую индексацию для заполнения столбцов. Но мой фрейм данных имеет около 50x10 ^ 6 строк и ~ 200 000 уникальных идентификаторов, так что это займет очень много времени. Я читал, что итерации по строкам фрейма данных неэффективны, но я не знаю, как применять альтернативные решения к моему набору данных.

Спасибо.

Ответы [ 2 ]

2 голосов
/ 29 октября 2019

Как насчет groupby().agg():

df.groupby('id', as_index=False).agg({'food':'nunique',
                      'fruit':'sum',
                     'score':'sum'})

Вывод:

     id  food  fruit  score
0  1001     3      1      1
1  1002     3      3      6
2  1003     2      1      3
0 голосов
/ 29 октября 2019

Поскольку pandas >= 0.25.0 у нас есть named aggregations для этого, где мы можем агрегировать и в то же время дать нашим столбцам более информативное имя, так как мы агрегируем:

Так что вВ этом примере мы можем сделать столбец unique за один раз.

df.groupby('id').agg(
    unique=('food', 'nunique'),
    fruits=('fruit', 'sum'),
    score=('score', 'sum')
).reset_index()

     id  unique  fruits  score
0  1001       3       1      1
1  1002       3       3      6
2  1003       2       1      3
...