Есть датафрейм df. Есть фича feat имеющая три категории cat1, cat2, и немногочисленная Unknown.
Я хочу избавиться от Unknown, раскидав ее по cat1 и cat2 так, чтобы она разлетелась по ним пропорционально их доле в датасете. То есть, если изначально было 45% cat1, 40% cat2 и 5% Unknown, то нужно, чтобы Unknown разлетелась в между cat1 и сat2 в соотношении 9/8.
В документации и блогах ничего подобного не нашел.
Ответ
Исходный DF:
In [67]: %paste
df = pd.DataFrame({'feat':np.random.choice(['cat1','cat2','Unknown'],
size=100,
p=[0.45,0.40,0.15])})
## -- End pasted text --
In [68]: df.feat.value_counts()
Out[68]:
cat1 49
cat2 36
Unknown 15
Name: feat, dtype: int64
Сначала найдем соотношение между cat1 и cat2
In [69]: pct = df.feat.value_counts() / len(df)
In [70]: ratio = pct.loc[['cat1','cat2']].min() / pct.loc[['cat1','cat2']].max()
In [71]: pct
Out[71]:
cat1 0.49
cat2 0.36
Unknown 0.15
Name: feat, dtype: float64
In [72]: ratio
Out[72]: 0.7346938775510204
теперь заменим строки с Unknown с таким же соотношением:
In [74]: df.loc[df['feat']=='Unknown', 'feat'] = \
...: np.random.choice([pct[['cat1','cat2']].idxmax(), pct[['cat1','cat2']].idxmin()],
...: size=df['feat'].eq('Unknown').sum(),
...: p=[ratio, 1-ratio])
...:
...:
In [75]: df.feat.value_counts()
Out[75]:
cat1 62
cat2 38
Name: feat, dtype: int64
проверка соотношения после замены значений:
In [76]: pct.loc[['cat1','cat2']].min() / pct.loc[['cat1','cat2']].max()
Out[76]: 0.7346938775510204
Комментариев нет:
Отправить комментарий