April 27, 2022

Заполнение пропусков категориальной модой

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

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

Для вычисления моды можно использовать метод mode, который возвращает набор наиболее часто встречающихся категорий (возможно пустой):

df['revenue'].mode()
df['revenue'].mode()[0]

пустая для категории (колонка gr_id) = 3:

display(df.loc[df.gr_id==3,'revenue'].mode())

Так можно заполнить модой все пропуски:

df['revenue'].fillna(df['revenue'].mode()[0])

Вот пример, когда заполнение надо сделать более дифференцированным способом, например, по группе:

df.groupby('gr_id')['revenue'].transform(
        lambda x: x.fillna((x.mode()[0] if x.count()!=0 else "unknown")))
# df.groupby('gr_id')['revenue'].transform(
#         lambda x: x.fillna((x.mode()[0] if not x.mode().empty else "unknown")))

Если кто-то не знаком с transform можете подробнее прочитать здесь.

Альтернативным способом является использование value_counts и idmax:

df.groupby('gr_id')['revenue'].transform(
    lambda x: x.fillna(x.value_counts().idxmax() if x.count()!=0 else 'unknown'))   
    

Сработает и так:

df['revenue'].fillna(df.groupby('gr_id')['revenue'].transform(
    lambda x:x.value_counts().idxmax() if x.count()!=0 else 'unknown')) 

Не пропустите ничего интересного и подписывайтесь на страницы канала в других социальных сетях:

Яндекс Дзен

Telegram