Spec-Zone.ru › pandas 0.24

Группировка: 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 позже), можно сделать следующее:

In [1]: df = pd.DataFrame([('bird', 'Falconiformes', 389.0),
   ...:                    ('bird', 'Psittaciformes', 24.0),
   ...:                    ('mammal', 'Carnivora', 80.2),
   ...:                    ('mammal', 'Primates', np.nan),
   ...:                    ('mammal', 'Carnivora', 58)],
   ...:                   index=['falcon', 'parrot', 'lion', 'monkey', 'leopard'],
   ...:                   columns=('class', 'order', 'max_speed'))
   ...: 

In [2]: df
Out[2]: 
          class           order  max_speed
falcon     bird   Falconiformes      389.0
parrot     bird  Psittaciformes       24.0
lion     mammal       Carnivora       80.2
monkey   mammal        Primates        NaN
leopard  mammal       Carnivora       58.0

# default is axis=0
In [3]: grouped = df.groupby('class')

In [4]: grouped = df.groupby('order', axis='columns')

In [5]: grouped = df.groupby(['class', 'order'])

Отображение можно указать различными способами:

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

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

Примечание

Строка, переданная в groupby, может ссылаться на столбец или уровень индекса. Если строка соответствует имени столбца и имени уровня индекса, будет поднято исключение ValueError.

In [6]: 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 [7]: df
Out[7]: 
     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 [8]: grouped = df.groupby('A')

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

Введено в версии 0.24.

Если у нас также есть MultiIndex в столбцах A и B, мы можем сгруппировать по всем столбцам, кроме указанных.

In [10]: df2 = df.set_index(['A', 'B'])

In [11]: grouped = df2.groupby(level=df2.index.names.difference(['B']))

In [12]: grouped.sum()
Out[12]: 
            C         D
A                      
bar -1.591710 -1.739537
foo -0.752861 -1.402938

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

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

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

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

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

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

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

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

In [19]: 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.24.2/user_guide/groupby.html

Spec-Zone.ru

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