Нужно посчитать долю каждой строки в сумме продаж своей группы по store: share = sales / sum(sales) внутри store. Какой вариант самый идиоматичный в pandas?

Adf["share"] = df.groupby("store")["sales"].sum() / df["sales"].sum()
Bdf["share"] = df["sales"] / df.groupby("store")["sales"].mean()
Cdf["share"] = df["sales"] / df.groupby("store")["sales"].transform("sum")
Ddf["share"] = df["sales"].apply(lambda x: x / df.groupby("store")["sales"].sum())
Правильный ответ. Для расчёта значений на уровне строк внутри групп используют .transform(), который сохраняет исходную длину DataFrame.

Разбор

.transform("sum") возвращает Series той же длины, что и исходный DataFrame, где каждой строке сопоставлена сумма её группы. Это позволяет делить df["sales"] поэлементно. Варианты с .sum() или .mean() без transform() дают агрегированный результат по группам и не совпадают по длине с исходными строками. apply() с обращением к groupby внутри лямбды работает медленно и непрозрачно, а ещё и считает не то — он применяет операцию к каждому скаляру.

Проверь себя · 1/3разбор после ответа
Какое выражение в pandas гарантированно вернёт объект DataFrame (а не Series) при выборе одного столбца с именем col?
Тренировать Python в Telegram

Ещё вопросы по теме «Pandas и DataFrame»