2014-12-14 3 views
2

Мне интересно, есть ли путинский способ заполнения нулей для категориальных данных путем случайного выбора из распределения уникальных значений. В основном пропорционально/случайное заполнение категоричных аннулирует на основе существующего распределения значений в столбце ...Заполнение нескольких нулей для категориальных данных

- Ниже приведен пример того, что я уже делаю

--I'm используя числа как категории, чтобы сэкономить время, я не знаю, как случайно входные буквы

import numpy as np 
import pandas as pd 
np.random.seed([1]) 
df = pd.DataFrame(np.random.normal(10, 2, 20).round().astype(object)) 
df.rename(columns = {0 : 'category'}, inplace = True) 
df.loc[::5] = np.nan 
print df 

    category 
0  NaN 
1  12 
2   4 
3   9 
4  12 
5  NaN 
6  10 
7  12 
8  13 
9   9 
10  NaN 
11  9 
12  10 
13  11 
14  9 
15  NaN 
16  10 
17  4 
18  9 
19  9 

Это, как я в настоящее время ввода значения

df.category.value_counts() 

9  6 
12 3 
10 3 
4  2 
13 1 
11 1 

df.category.value_counts()/16 

9  0.3750 
12 0.1875 
10 0.1875 
4  0.1250 
13 0.0625 
11 0.0625 

# to fill categorical info based on percentage 
category_fill = np.random.choice((9, 12, 10, 4, 13, 11), size = 4, p = (.375, .1875, .1875, .1250, .0625, .0625)) 
df.loc[df.category.isnull(), "category"] = category_fill 

Final outpu т, требуется некоторое время, чтобы написать

df.category.value_counts() 

9  9 
12 4 
10 3 
4  2 
13 1 
11 1 

Есть ли более быстрый способ сделать это или функцию, которая будет служить этой цели?

Спасибо за любую помощь!

ответ

1

Вы можете использовать stats.rv_discrete:

from scipy import stats 

counts = df.category.value_counts() 
dist = stats.rv_discrete(values=(counts.index, counts/counts.sum())) 
fill_values = dist.rvs(size=df.shape[0] - df.category.count()) 
df.loc[df.category.isnull(), "category"] = fill_values 

EDIT: Для общих данных (не ограничивается целыми числами), вы можете сделать:

dist = stats.rv_discrete(values=(np.arange(counts.shape[0]), 
           counts/counts.sum())) 
fill_idxs = dist.rvs(size=df.shape[0] - df.category.count()) 
df.loc[df.category.isnull(), "category"] = counts.iloc[fill_idxs].index.values 
+0

Это прекрасно работает на тестовых данных! Но когда я пытаюсь использовать его на данных, которые являются строками, я получаю ошибку. «не удалось преобразовать строку в float: b» Моя ошибка в том, что вы не используете данные, которые являются строками в образце. Есть ли способ для работы над строками в дополнение или вместо этого? Спасибо! –

+0

@DavidFeldman, Да, есть! Я обновил свой ответ. – elyase

+0

Это так здорово! Спасибо!!! –

Смежные вопросы