April 17, 2022

Заполнение ячейки групповыми агрегациями

Рассмотрим, как заполнить пропуски в колонке групповыми значениями по не пустым ячейкам. Для примера возьмем таблицу:

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

Пусть мы хотим заполнить столбец дохода (revenue) групповыми медианами (по столбцу gr_id). Для этого можно в fillna использовать метод transform (о нем подробнее писал здесь):

df['revenue'].fillna(df.groupby('gr_id')['revenue'].transform('median'))

Групповые значения fillna заполняет только в пустые места.

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

df_gr = df.groupby('gr_id')['revenue'].median()
df_gr

теперь присоединяем и заполняем пропуски:

df_cor = df.merge(df_gr, left_on = 'gr_id', right_index=True).sort_index()
df_cor['revenue'] = df_cor['revenue_x'].fillna(df_cor['revenue_y'])
df_cor

Групповые значения можно получать и на основании нескольких столбцов. В этом случае вам пригодится метод apply. Для примера рассчитаем для df_cor групповое медианное значение отношения 'revenue' к 'gr_id':

df_cor.groupby('gr_id')[['revenue', 'gr_id']].apply(lambda x: (x['revenue']/x['gr_id']).median())

Теперь можно аналогично примеру выше приджойнить колонку к основной таблице и получить искомый столбец.

Операции заполнения групповыми статистиками достаточно распространены. Одним из типичных примеров является нахождение неизвестной жилой площади квартиры при имеющейся общей. Для этого сначала получаем среднее отношение жилой площади к общей по заполненным данным, а затем умножаем на него общую площадь.