df.groupby () - как агрегировать данные, где важен порядок сгруппированных данных? - PullRequest
2 голосов
/ 02 апреля 2019

Как я могу агрегировать данные, когда важен порядок сгруппированных данных? (бонусные баллы, если это можно сделать элегантным векторизованным способом).Если это было ясно как грязь, позвольте мне объяснить на примере.


Допустим, у меня есть данные в df:

id    month              value
------------------------------
001   2019-01-01 (Jan)     111
001   2019-02-01 (Feb)     222
001   2019-03-01 (Mar)     333

002   2019-01-01 (Jan)       0
002   2019-02-01 (Feb)       0
002   2019-03-01 (Mar)      25

...   ...                  ...

999   2019-01-01 (Jan)     800
999   2019-02-01 (Feb)     600
999   2019-03-01 (Mar)     400

Я могу использовать groupby для агрегированияданные по каждому id:

df.groupby('id')['value'].agg([numpy.sum, numpy.mean])

Если я использую numpy.sum, numpy.mean, numpy.max и т. д. в качестве функции агрегирования, порядок сгруппированного изолированного массива не 'Не имеет значения (например, [111, 222, 333] для id=001) - результат всегда будет одинаковым.


Однако, есть некоторые агрегации, где порядок имеет значение - например, я могу захотетьрассчитать:

  • средневзвешенное значение (например, если более поздние значения имеют больший вес)
  • изменение от начала до конца (например, Mar - Jan)
  • и т. Д.

В настоящее время я перебираю каждый id, а затем:

  1. фильтрую данные через df[df['id']==id]
  2. получить список кортежей со значением месяца, например, [(Jan,111), (Feb,222), (Mar,333)]
  3. список сортировки на основе первого элемента каждого кортежа, т.е. 'month'
  4. выполнить агрегирование

Например, еслиЯ просто хотел найти разницу между первым и последним элементами этого отсортированного массива , и в итоге я получу следующее:

id    finish_minus_start
------------------------
001                  222
002                   25
...                  ...
999                 -400

Как можноЯ объединяю данные, когда важен порядок сгруппированных данных?

Могу ли я сделать это более эффективно, используя векторизацию вместо циклического прохождения каждого id?

1 Ответ

0 голосов
/ 03 апреля 2019

Надеюсь, это то, что вы искали.Вы можете использовать агрегаты и установить свою собственную функцию.Я взял пример из двух ссылок Обобщение и группировка данных и Первая и последняя функции и немного поиграл.

df= df.set_index('date')
aggregations = {
    'value': lambda x: x.loc[x.index.max()] - x.loc[x.index.min()]
}
print(df.groupby('id').agg(aggregations))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...