Функция 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: Группировка по одному столбцу

Самый базовый способ — группировка по значениям одного столбца. Предположим, у нас есть таблица данных о продажах, и нужно вычислить суммарные продажи по регионам.

Пример

import pandas as pd

# Создаём простой 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

Анализ кода:

  1. df.groupby('地区')Данные разделены на три группы в соответствии со значениями в столбце 'Region': East, South, North.
  2. ['销售额'].sum()Это означает, что только столбец 'Sales' агрегируется с помощью sum.
  3. as_index=True(значение по умолчанию) возвращает Series с регионом в качестве индекса;as_index=FalseКогда ..., возвращаемый DataFrame сохраняет регион как обычный столбец, что больше подходит для последующей обработки.

Пример 2: Группировка по нескольким столбцам

Иногда требуется группировать одновременно по нескольким столбцам, например по региону и продукту, чтобы рассчитать продажи.

Пример

import pandas as pd

# Создать данные о продажах
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()Помимо группировки по именам столбцов, можно также определять правила группировки с помощью словарей или функций, что очень полезно, когда требуется пользовательская логика группировки.

Пример

import pandas as pd

# Создать данные об оценках студентов
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: Перебор групп после группировки

Иногда нам нужно выполнять более сложные пользовательские операции над каждой группой; в этом случае мы можем перебирать объекты групп.

Пример

import pandas as pd

# Создать данные о продажах
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()и т. д.) или итерировании будет выполнено фактическое вычисление.


Распространённые функции Pandas

Другие расширения