GroupBy в Pandas

groupby — это разбиение таблицы на группы по значениям одного или нескольких столбцов и применение к каждой группе функции: средняя, сумма, максимум, своя лямбда. Принцип называется split-apply-combine: «разбить — применить — склеить».

Когда использовать

  • Среднее напряжение батареи по каждому роботу.

  • Сумма событий по дням недели.

  • Топ-1 датчик в каждой группе.

Пример 1. Среднее по группе

import pandas as pd

df = pd.DataFrame({
    "device": ["bot1", "bot1", "bot2", "bot2"],
    "battery": [3.7, 3.6, 4.0, 3.9],
})
print(df.groupby("device")["battery"].mean())

Output:

device
bot1    3.65
bot2    3.95
Name: battery, dtype: float64

Пример 2. Несколько агрегаций сразу

import pandas as pd

df = pd.DataFrame({
    "device": ["bot1", "bot1", "bot2", "bot2"],
    "battery": [3.7, 3.6, 4.0, 3.9],
})
print(df.groupby("device")["battery"].agg(["mean", "min", "max"]))

Output:

        mean  min  max
device
bot1    3.65  3.6  3.7
bot2    3.95  3.9  4.0

Пример 3. Группировка по двум столбцам

import pandas as pd

df = pd.DataFrame({
    "device": ["bot1", "bot1", "bot2", "bot2"],
    "sensor": ["temp", "hum", "temp", "hum"],
    "v": [22, 55, 24, 50],
})
print(df.groupby(["device", "sensor"])["v"].mean())

Output:

device  sensor
bot1    hum       55.0
        temp      22.0
bot2    hum       50.0
        temp      24.0
Name: v, dtype: float64

Пример 4. Подсчёт строк

import pandas as pd

df = pd.DataFrame({"device": ["bot1", "bot2", "bot1", "bot1"]})
print(df.groupby("device").size())

Output:

device
bot1    3
bot2    1
dtype: int64

Пример 5. transform

Добавить столбец с групповой средней:

import pandas as pd

df = pd.DataFrame({
    "device": ["bot1", "bot1", "bot2"],
    "v": [10, 20, 30],
})
df["group_mean"] = df.groupby("device")["v"].transform("mean")
print(df)

Output:

  device   v  group_mean
0   bot1  10        15.0
1   bot1  20        15.0
2   bot2  30        30.0

Пример 6. filter

Оставить только группы, где сумма > порога:

import pandas as pd

df = pd.DataFrame({"device": ["a", "a", "b"], "v": [10, 20, 5]})
print(df.groupby("device").filter(lambda g: g["v"].sum() > 10))

Output:

  device   v
0      a  10
1      a  20

Пример 7. Своя функция

import pandas as pd

df = pd.DataFrame({"device": ["a", "a", "b", "b"], "v": [1, 5, 3, 9]})
print(df.groupby("device")["v"].agg(lambda x: x.max() - x.min()))

Output:

device
a    4
b    6
Name: v, dtype: int64

Подводные камни

  • По умолчанию ключ группировки становится индексом результата — as_index=False оставит обычные столбцы.

  • NaN в ключе группировки исключаются — иногда это сюрприз.

  • Цикл for k, g in df.groupby(...) работает, но медленный — для скорости используйте agg/transform.

См. также

Примечание

Лицензия и источники

Техническое описание адаптировано из официальной документации Pandas (https://pandas.pydata.org/docs/), BSD-3-Clause License. Перевод на русский, примеры и пояснения — © AlashEd Wiki.