Перейти к содержимому
Теория · NumPy и pandas · урок 10 из 12

Группировка и медиана

Средняя зарплата по всей таблице мало что говорит, если в ней несколько команд. Нужно среднее по каждой команде отдельно. В pandas для этого не нужен цикл:

Python
import pandas as pd

df = pd.DataFrame({
    "team": ["ml", "ml", "ml", "web", "web", "web", "web"],
    "level": ["jun", "mid", "sen", "jun", "jun", "mid", "sen"],
    "salary": [100, 120, 140, 90, 95, 105, 610],
})
means = df.groupby("team")["salary"].mean()
print(means.to_dict())  # {'ml': 120.0, 'web': 225.0}
print(df.groupby("team")["salary"].count().to_dict())  # {'ml': 3, 'web': 4}

Группировка

Группировка (grouping) делит строки по значению столбца. Вызов df.groupby("team") собирает строки с "ml" в одну группу, а строки с "web" — в другую. Затем выбирают столбец, ["salary"], и считают по каждой группе одно число: mean, median, sum или count.

Результат — столбец Series, где каждой группе соответствует её число. Метод to_dict превращает его в словарь. Метод count считает заполненные значения, поэтому в web их четыре. Пропуски не учитываются: если в группе одни пропуски, mean и median дают ей NaN, а count — 0.

Медиана

У команды web среднее 225.0, хотя трое из четверых получают не больше 105. Одна зарплата 610 тянет среднее вверх. Медиана (median) — значение посередине упорядоченного списка, и от одного большого числа она почти не зависит.

Чтобы найти медиану, значения сортируют: у web это 90, 95, 105, 610. При чётном числе значений медиана равна среднему двух центральных значений: у web это (95 + 105) / 2.

Python
medians = df.groupby("team")["salary"].median()
print(medians.to_dict())  # {'ml': 120.0, 'web': 100.0}

Зарплаты, цены и доходы обычно образуют скошенные данные (skewed data): большинство значений небольшие, а редкие очень большие. На таких данных медиана описывает типичный объект лучше среднего. У команды ml значения симметричны, и обе меры дают 120.0.

Если среднее заметно больше медианы, в данных есть редкие большие значения. Среднее при этом не бесполезно: умноженное на число сотрудников, оно даёт фонд оплаты, а медиана — нет.

Частая ошибка

Среднее посчитали по всей группировке, не выбрав столбец:

Python
print(df.groupby("team").mean())  # ✗
TEXT
TypeError: agg function failed [how->mean,dtype->object]

В таблице есть текстовый столбец level, и pandas пытается усреднить его тоже. До версии 2.0 pandas отбрасывал такие столбцы, поэтому в старых примерах этот вызов встречается часто. Выберите числовой столбец перед подсчётом: df.groupby("team")["salary"].mean().

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом