Spec-Zone.ru › pandas 0.23

Группировка: split-apply-combine

Под «группировкой» мы понимаем процесс, включающий один или несколько следующих шагов:

  • Разделение данных на группы по определенным критериям.
  • Применение функции к каждой группе независимо.
  • Объединение результатов в структуру данных.

Из этих шагов наиболее простым является шаг разделения. На самом деле, во многих ситуациях нам может потребоваться разделить набор данных на группы и выполнить какие-то действия с этими группами. На шаге применения мы можем захотеть выполнить одно из следующих действий:

  • Агрегация: вычислить сводную статистику (или несколько статистик) для каждой группы. Некоторые примеры:

    • Вычислить групповые суммы или средние значения.
    • Вычислить размеры/количество элементов в каждой группе.
  • Трансформация: выполнить вычисления, специфичные для каждой группы, и вернуть объект с аналогичной индексацией. Некоторые примеры:

    • Нормализация данных (z-оценка) внутри группы.
    • Заполнение пропусков (NaN) внутри групп значением, полученным из каждой группы.
  • Фильтрация: отбросить некоторые группы, основываясь на групповых вычислениях, которые возвращают True или False. Некоторые примеры:

    • Отбросить данные, принадлежащие группам с небольшим количеством элементов.
    • Отфильтровать данные на основе групповой суммы или среднего значения.
  • Некоторое сочетание вышеперечисленного: GroupBy проанализирует результаты шага применения и попытается вернуть разумный объединенный результат, если он не подходит ни к одной из вышеперечисленных категорий.

Поскольку набор методов экземпляров объектов в структурах данных pandas обычно богат и выразителен, мы часто просто хотим вызвать, скажем, функцию DataFrame для каждой группы. Название GroupBy должно быть знакомо тем, кто использовал инструмент на основе SQL (или itertools), в котором вы можете написать код, подобный:

SELECT Column1, Column2, mean(Column3), sum(Column4)
FROM SomeTable
GROUP BY Column1, Column2

Мы стремимся сделать такие операции естественными и лёгкими для выражения с использованием pandas. Мы рассмотрим каждую область функциональности GroupBy, а затем предоставим некоторые нетривиальные примеры / варианты использования.

См. справочник по рецептам для некоторых расширенных стратегий.

Разделение объекта на группы

Объекты pandas можно разделить по любому из их осей. Абстрактное определение группировки заключается в предоставлении сопоставления меток с именами групп. Для создания объекта GroupBy (подробнее о том, что такое объект GroupBy, позже) вы можете сделать следующее:

# default is axis=0
>>> grouped = obj.groupby(key)
>>> grouped = obj.groupby(key, axis=1)
>>> grouped = obj.groupby([key1, key2])

Сопоставление можно указать многими способами:

  • Функция Python, которая вызывается для каждой метки оси.
  • Список или массив NumPy той же длины, что и выбранная ось.
  • Словарь или Series, предоставляющий label -> group name отображение.
  • Для объектов DataFrame, строка, указывающая столбец для группировки. Конечно, df.groupby('A') — это просто синтаксический сахар для df.groupby(df['A']), но это упрощает жизнь.
  • Для объектов DataFrame, строка, указывающая уровень индекса для группировки.
  • Список из любого из вышеперечисленного.

В совокупности мы называем объекты группировки ключами. Например, рассмотрим следующий DataFrame.

Примечание

Новое в версии 0.20.

Строка, переданная в groupby, может относиться как к столбцу, так и к уровню индекса. Если строка совпадает как с именем столбца, так и с именем уровня индекса, выдается предупреждение, и приоритет отдаётся столбцу. В будущих версиях это приведёт к ошибке неоднозначности.

In [1]: df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
   ...:                           'foo', 'bar', 'foo', 'foo'],
   ...:                    'B' : ['one', 'one', 'two', 'three',
   ...:                           'two', 'two', 'one', 'three'],
   ...:                    'C' : np.random.randn(8),
   ...:                    'D' : np.random.randn(8)})
   ...: 

In [2]: df
Out[2]: 
     A      B         C         D
0  foo    one  0.469112 -0.861849
1  bar    one -0.282863 -2.104569
2  foo    two -1.509059 -0.494929
3  bar  three -1.135632  1.071804
4  foo    two  1.212112  0.721555
5  bar    two -0.173215 -0.706771
6  foo    one  0.119209 -1.039575
7  foo  three -1.044236  0.271860

Для DataFrame мы получаем объект GroupBy, вызвав groupby(). Мы можем естественным образом сгруппировать данные по столбцам A или B, или по обоим:

In [3]: grouped = df.groupby('A')

In [4]: grouped = df.groupby(['A', 'B'])

Это разделит DataFrame по своему индексу (строкам). Мы также можем разделить по столбцам:

In [5]: def get_letter_type(letter):
   ...:     if letter.lower() in 'aeiou':
   ...:         return 'vowel'
   ...:     else:
   ...:         return 'consonant'
   ...: 

In [6]: grouped = df.groupby(get_letter_type, axis=1)

Объекты pandas Index поддерживают дублирующие значения. Если в операции groupby используется не уникальный индекс в качестве ключа группировки, все значения для одного значения индекса будут считаться одной группой, и поэтому в результате агрегационных функций будут содержаться только уникальные значения индекса:

In [7]: lst = [1, 2, 3, 1, 2, 3]

In [8]: s = pd.Series([1, 2, 3, 10, 20, 30], lst)

In [9]: grouped = s.groupby(level=0)

In [10]: grouped.first()
Out[10]: 
1    1
2    2
3    3
dtype: int64

In [11]: grouped.last()

© 2008–2012, AQR Capital Management, LLC, Lambda Foundry, Inc. and PyData Development Team
Licensed under the 3-clause BSD License.
https://pandas.pydata.org/pandas-docs/version/0.23.4/groupby.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API