Функция Pandas df.groupby()
Часто используемые функции Pandas
groupby()Это одна из самых мощных функций групповых операций в Pandas. Она позволяет разделять данные на разные группы на основе значений одного или нескольких столбцов, а затем выполнять различные операции с каждой группой.
Проще говоря,groupby()она реализует"Split-Apply-Combine"(разделяй-применяй-объединяй) рабочий процесс: сначала разделяет данные по условиям, применяет соответствующую функцию к каждой группе и в конце объединяет результаты.
Это очень распространено в анализе данных, например, расчёт средней зарплаты сотрудников по отделам, суммирование продаж по месяцам и подсчёт пользователей по регионам.
Базовый синтаксис и параметры
groupby()Это метод DataFrame, вызываемый через оператор точки.для вызова. После вызова он возвращаетGroupByобъект. Этот объект не отображает результаты напрямую; его нужно использовать вместе с агрегатными функциями.
Формат синтаксиса
DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, observed=False, dropna=True)
Описание параметра
| Параметр | Type | Описание | Значение по умолчанию |
|---|---|---|---|
| от | str, list или dict | Имя столбца или список имён столбцов, используемых для группировки. Если это словарь или функция, группировка выполняется на основе результатов этого словаря или функции. | Отсутствует |
| axis | int | Направление оси для группировки; 0 означает по строкам (по умолчанию), 1 — по столбцам. | 0 |
| level | int или str | Если это MultiIndex, группировать по указанному уровню. | Отсутствует |
| as_index | bool | Если True, столбцы группировки будут использоваться как индекс возвращаемого результата; если False, столбцы группировки будут сохранены как обычные столбцы. | True |
| сортировка | bool | Следует ли сортировать метки групп. Установка значения False может повысить производительность. | True |
| group_keys | bool | При вызовеapply()следует ли добавлять ключи группировки как индекс в результате. |
True |
| observed | bool | Если True, отображаются только фактически наблюдаемые значения категориальных переменных, а не все возможные значения. | False |
| dropna | bool | Если True, группы, содержащие значения NA/null, будут удалены. | True |
Возвращаемое значение
- Тип возвращаемого значения:
DataFrameGroupByилиSeriesGroupByобъект - Описание: Он возвращает объект группировки, а не окончательный результат. Нужно вызвать функцию агрегации (например,
sum()、mean()、count()и т. д.), чтобы получить конкретный результат вычисления.
Примеры
Давайте тщательно освоим ... на серии примеров от простого к сложномуgroupby()использование df.groupby().
Пример 1: Группировка по одному столбцу
Самый базовый способ — группировка по значениям одного столбца. Предположим, у нас есть таблица данных о продажах, и нужно вычислить суммарные продажи по регионам.
Пример
# Создаём простой DataFrame с данными о продажах
# Имитируем таблицу, содержащую регион, продукт и сумму продаж
data = {
'Region': ['North', 'East', 'South', 'North', 'East', 'South', 'North', 'East'],
'Product': ['A', 'B', 'C', 'B', 'A', 'C', 'A', 'B'],
'Sales': [1000, 2000, 1500, 1800, 2200, 1600, 1200, 2100]
}
# Создать DataFrame
df = pd.DataFrame(data)
print("Исходные данные:")
print(df)
print()
# Группируем по столбцу 'Region' и вычисляем суммарные продажи для каждого региона
# as_index=True означает, что регион возвращается в качестве индекса
grouped = df.groupby('Region', as_index=True)['Sales'].sum()
print("Общий объём продаж после группировки по региону:")
print(grouped)
print()
# Когда as_index=False, столбец группировки сохраняется как обычный столбец
grouped_df = df.groupby('Region', as_index=False)['Sales'].sum()
print("Результат при as_index=False:")
print(grouped_df)
Ожидаемый вывод:
原始数据: 地区 产品 销售额 0 华东 B 2000 1 华南 C 1500 2 华北 A 1000 3 华东 B 1800 4 华南 C 2200 5 华北 A 1600 6 华东 A 1200 7 华南 B 2100 按地区分组后的总销售额: 地区 华东 7100 华南 7300 华北 3600 dtype: int64 as_index=False 时的结果: 地区 销售额 0 华东 7100 1 华南 7300 2 华北 3600
Анализ кода:
df.groupby('地区')Данные разделены на три группы в соответствии со значениями в столбце 'Region': East, South, North.['销售额'].sum()Это означает, что только столбец 'Sales' агрегируется с помощью sum.as_index=True(значение по умолчанию) возвращает Series с регионом в качестве индекса;as_index=FalseКогда ..., возвращаемый DataFrame сохраняет регион как обычный столбец, что больше подходит для последующей обработки.
Пример 2: Группировка по нескольким столбцам
Иногда требуется группировать одновременно по нескольким столбцам, например по региону и продукту, чтобы рассчитать продажи.
Пример
# Создать данные о продажах
data = {
'Region': ['North', 'East', 'South', 'North', 'East', 'South', 'North', 'East'],
'Product': ['A', 'B', 'C', 'B', 'A', 'C', 'A', 'B'],
'Sales': [1000, 2000, 1500, 1800, 2200, 1600, 1200, 2100]
}
df = pd.DataFrame(data)
print("Исходные данные:")
print(df)
print()
# Сгруппировать по столбцам 'Region' и 'Product', чтобы рассчитать общий объем продаж
# Использовать список для указания нескольких столбцов группировки
grouped = df.groupby(['Region', 'Product'], as_index=False)['Sales'].sum()
print("Общий объем продаж после группировки по региону и продукту:")
print(grouped)
print()
# Использовать pivot_table, чтобы отобразить результаты более наглядно
pivot = df.pivot_table(values='Sales', index='Region', columns='Product', aggfunc='sum', fill_value=0)
print("Отображено с помощью pivot_table:")
print(pivot)
Ожидаемый вывод:
原始数据: 地区 产品 销售额 0 华北 A 1000 1 华东 B 2000 2 华南 C 1500 3 华北 B 1800 4 华东 A 2200 5 华南 C 1600 6 华北 A 1200 7 华东 B 2100 按地区和产品分组后的总销售额: 地区 产品 销售额 0 华东 A 2200 1 华东 B 4100 2 华南 C 3100 3 华北 A 2200 4 华北 B 1800 使用 pivot_table 展示: 产品 A B C 地区 华北 2200 1800 0 华东 2200 4100 0 华南 0 0 3100
Анализ кода:
['Region', 'Product']Использование списка позволяет группировать одновременно по нескольким столбцам, а результат создаёт многоуровневый индекс.as_index=FalseКогда ..., столбцы группировки сохраняются как обычные столбцы в результате, что удобно для просмотра и последующей обработки.pivot_table()Он предоставляет аналогичную функцию кросс-табуляции, представляя результаты группировки более интуитивно понятным способом.
Пример 3: группировка с помощью словарей и функций
groupby()Помимо группировки по именам столбцов, можно также определять правила группировки с помощью словарей или функций, что очень полезно, когда требуется пользовательская логика группировки.
Пример
# Создать данные об оценках студентов
data = {
'Имя': ['Чжан Сань', 'Ли Сы', 'Ван У', 'Чжао Лю', 'Сунь Ци', 'Чжоу Ба'],
'Китайский': [85, 92, 78, 88, 95, 82],
'Математика': [90, 85, 92, 78, 88, 91],
'Английский': [88, 90, 85, 92, 87, 89]
}
df = pd.DataFrame(data)
print("Исходные данные об оценках студентов:")
print(df)
print()
# 1. Использование словаря для пользовательской группировки
# Предположим, мы хотим сгруппировать по "фамилии" (Чжан, Ли, Ван как одна группа, Чжао, Сунь, Чжоу как другая группа)
def get_surname_group(name):
"""Возвращает название группы на основе фамилии"""
if name in ['Чжан Сань', 'Ли Сы', 'Ван У']:
return 'Группа 1'
else:
return 'Группа 2'
# Использование функции apply для группировки
grouped = df.groupby(get_surname_group).mean(numeric_only=True)
print("Используйте функцию для определения пользовательской группировки (вычислите средний балл каждой группы):")
print(grouped)
print()
# 2. Использование словаря для сопоставления группировки для конкретного столбца
# Разделите баллы по китайскому языку на группы "Отлично" и "Хорошо" на основе числовых интервалов
score_mapping = {
'Chinese': lambda x: 'Excellent' if x >= 90 else 'Good'
}
# Сгруппировать столбец Chinese по условию
grouped_by_score = df.groupby(lambda x: 'Excellent' if df.loc[x, 'Chinese'] >= 90 else 'Good').mean(numeric_only=True)
print("Группировка по баллам Chinese (>=90 — Excellent):")
print(grouped_by_score)
Ожидаемый вывод:
原始学生成绩数据:
姓名 语文 数学 英语
0 张三 85 90 88
1 李四 92 85 90
2 王五 78 92 85
3 赵六 88 78 92
4 孙七 95 88 87
5 周八 82 91 89
使用函数自定义分组(计算每组平均分):
语文 数学 英语
姓名
第一组 85.000000 89.000000 87.666667
第二组 88.333333 85.666667 89.333333
按语文成绩分组(>=90为优秀):
语文 数学 英语
语文
优秀 93.500000 86.500000 88.500000
良好 83.250000 89.500000 88.750000
Анализ кода:
- Группировка с помощью пользовательской функции может обрабатывать сложную логику группировки; достаточно, чтобы функция возвращала значение для группировки.
- Использование
numeric_only=Trueпараметр может ограничить агрегацию числовыми столбцами, что позволяет избежать ошибок при работе с нечисловыми столбцами (например, именами). - С помощью сопоставления словаря можно реализовать требование "разделения разных столбцов на разные группы в зависимости от условий".
Пример 4: Перебор групп после группировки
Иногда нам нужно выполнять более сложные пользовательские операции над каждой группой; в этом случае мы можем перебирать объекты групп.
Пример
# Создать данные о продажах
data = {
'Region': ['North', 'East', 'South', 'North', 'East', 'South'],
'Product': ['A', 'B', 'C', 'B', 'A', 'C'],
'Sales amount': [1000, 2000, 1500, 1800, 2200, 1600]
}
df = pd.DataFrame(data)
print("Исходные данные:")
print(df)
print()
# Перебор каждой группы для обработки
print("Подробная информация для каждой группы:")
print("-" * 40)
for group_name, group_data in df.groupby('Region'):
print(f"nИмя группы: {group_name}")
print(f"Количество строк в этой группе: {len(group_data)}")
print(f"Общий объем продаж для этой группы: {group_data['Sales amount'].sum()}")
print(f"Средний объем продаж для этой группы: {group_data['Sales amount'].mean():.2f}")
print("-" * 40)
Ожидаемый вывод:
原始数据: 地区 产品 销售额 0 华东 B 2000 1 华南 C 1500 2 华北 A 1000 3 华东 B 1800 4 华南 C 2200 5 华北 B 1800 每个分组的详细信息: ---------------------------------------- 分组名称: 华东 该组数据行数: 2 该组销售总额: 3800 该组平均销售额: 1900.00 ---------------------------------------- 分组名称: 华南 该组数据行数: 2 3700 1850.00 ---------------------------------------- 分组名称: 华北 该组数据行数: 2 2800 1400.00 ----------------------------------------
Пояснение к коду:
groupby()Возвращаемый сгруппированный объект можно перебирать напрямую; каждая итерация возвращает кортеж: (имя группы, данные этой группы).- Таким образом, вы можете выполнять сколь угодно сложные пользовательские операции над каждой группой.
- В практических приложениях этот метод часто используется для создания сложных отчётов или очистки данных.
Совет:
groupby()Возвращаемый объект GroupBy является «лениво выполняемым» и не вычисляет результаты сразу. Только при вызове агрегатных функций (таких какsum()、mean()、count()и т. д.) или итерировании будет выполнено фактическое вычисление.
Другие расширения