April 29, 2022

Основные агрегирующие функции в Pandas

Рассмотрим основных агрегирующие функции в Pandas. В качестве демонстрационного датафрейма используем следующий:

import pandas as pd
import numpy as np
df = pd.DataFrame([['Иванов ИИ', 1, 12], ['Федоров АК', 2, np.nan], 
                   ['Арсентьева ВБ', 1, 13],['Черкасова АА', 1, 13],
                  ['Чувашов ВК', 1, None], ['Галанова ББ', 2, 14]], 
                  columns=['fio', 'gr_id', 'revenue'])
df

Сходство некоторых функций порождает непонимание и неверное их использование, например, часто для подсчета доли пустых
ячеек используется такая форма - df['revenue'].isna().sum()/df['revenue'].count(). Однако это является неправильным, так как count подсчитывает количество ненулевых значений, а не их общее число. В то же время долю можно получить функцией mean:

df['revenue'].isna().sum()/df['revenue'].count(), df['revenue'].isna().mean()

Вот список самых распространенных функций:

count - количество ненулевых значений
len - общее количество значений (включая пустые)
size - общее количество значений (применяется странно)
nunique - количество уникальных значений
min - минимум
max - максимум
std - стандартное отклонение
sum - сумма
mean - среднее
median - медиана
var - дисперсия
quantile - квантиль

О том, как использовать собственные функции, писал ранее.

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

Распространенным "костылем" является попытка подсчитать количество значений в группе по некому дополнительному столбцу с помощью count, хотя это приведет к неправильному результату, если в нем есть пропуски. Правильным решением является группировка и вывод метода size без использования лишних столбцов, сравните:

df.groupby('gr_id').size(), df.groupby('gr_id')['revenue'].count()

Остановимся на особенностях size. В методе groupby size и len (обратите внимание, что len вызываем по ссылке) выводят одинаковый результат для выделенного или нескольких столбцов:

df.groupby('gr_id')['revenue'].agg(['size', 'count', len])

В методе pivot_table, чтобы size заработала, надо в values передавать список:

df.pivot_table(index='gr_id', values='revenue', aggfunc='size')
df.pivot_table(index='gr_id', values=['revenue'], aggfunc='size')

Эта особенность проявляется и в форме мультииндекса по столбцам, когда мы в aggfunc передаем еще несколько агрегирующих функций:

df.pivot_table(index='gr_id', values=['revenue'], aggfunc=['count', len, 
                                                         'size'])