.

Сделать репост в соц сети!

Показаны сообщения с ярлыком Снижение числа уровней категориальной переменной Pandas Python. Показать все сообщения
Показаны сообщения с ярлыком Снижение числа уровней категориальной переменной Pandas Python. Показать все сообщения

понедельник, 24 декабря 2018 г.

Снижение числа уровней категориальной переменной Pandas Python





Задачка простая, но мне она показалась очень интересной, и я вынес ее в блог.
Задача часто встречается в наших HR данных, смысл ее в том, что в категориальной переменной много уровней с очень низкой частотой, и мы должны эти уровни переменной вынести в один уровень "другое", чтобы анализ был корректным.

Решение


Загружаем библиотеки
import numpy as np
import pandas as pd
В качестве toy example такой датафрейм
df = pd.DataFrame({'Город':
'Москва Москва Москва Москва Москва Москва Санкт-Петербург Санкт-Петербург Санкт-Петербург Новосибирск Новосибирск Красноярск Магадан'
                   .split()})
df
 Город
0 Москва
1 Москва
2 Москва
3 Москва
4 Москва
5 Москва
6 Санкт-Петербург
7 Санкт-Петербург
8 Санкт-Петербург
9 Новосибирск
10 Новосибирск
11 Красноярск
12 Магадан
Сначала мы считаем количество значений
val = pd.value_counts(df['Город'])
val
Москва             6
Санкт-Петербург    3
Новосибирск        2
Магадан            1
Красноярск         1
Name: Город, dtype: int64
А потом пользуемся замечательной формулой pandas.Series.lt


mask = val.lt(2)
mask 
Москва             False
Санкт-Петербург    False
Новосибирск        False
Магадан             True
Красноярск          True
Name: Город, dtype: bool
Мы указали все города, частота которых менее 2 раз. А далее аналог формулы ЕСЛИ в excel
df['city']  = np.where(df['Город'].isin(val[mask].index),'другое',df['Город'] ).astype(object)
И проверяем
pd.crosstab(df['Город'], df['city'])
city      Москва Новосибирск Санкт-Петербург другое
Город    
Красноярск 0 0     0           1
Магадан         0 0     0           1
Москва         6 0     0           0
Новосибирск 0 2     0           0
Санкт-Петербург 0 0     3           0
Сошлось.
А если мы хотим задать порог не в абсолютных числах, а в %? Уровнем статистической значимости считают 5%, поэтому мы можем смело его задавать.
Правда я ниже укажу не 5, а 10 %, потому что в нашем датасете нет значений менее 5 %. Мы меняем только эту формулу, остальное все тоже самое
mask = (val/val.sum() * 100).lt(10)
Все. Можно применять