Группировка: split-apply-combine
Под «группировкой» мы понимаем процесс, включающий один или несколько из следующих шагов
- Разделение данных на группы на основе определённых критериев
- Применение функции к каждой группе независимо
- Объединение результатов в структуру данных
Из этих шагов этап разделения является наиболее простым. На самом деле, во многих ситуациях вы можете захотеть разделить набор данных на группы и выполнить какие-либо действия с этими группами самостоятельно. На этапе применения мы можем захотеть выполнить одно из следующих действий:
-
Агрегирование: вычисление сводной статистики (или статистик) по каждой группе. Некоторые примеры:
- Вычисление сумм или средних значений по группам
- Вычисление размеров / количества элементов в группах
-
Трансформация: выполнение вычислений, специфичных для группы, и возврат данных с аналогичной индексацией. Некоторые примеры:
- Стандартизация данных (z-счет) внутри группы
- Заполнение пропусков (NA) в группах значениями, полученными из каждой группы
-
Фильтрация: отбрасывание некоторых групп в соответствии с вычислением по группам, которое возвращает 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
Мы можем естественным образом сгруппировать данные по столбцам 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.21.1/groupby.html