2017-01-26 9 views
4

У меня есть столбец в области данных, который имеет категориальные данные, но некоторые данные отсутствуют, то есть NaN. Я хочу провести линейную интерполяцию по этим данным, чтобы заполнить недостающие значения, но я не уверен, как это сделать. Я не могу отказаться от NaN, чтобы превратить данные в категориальный тип, потому что мне нужно их заполнить. Простой пример, демонстрирующий, что я пытаюсь сделать.Pandas - Обработка NaNs в категориальных данных

col1 col2 
5  cloudy 
3  windy 
6  NaN 
7  rainy 
10 NaN 

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

col2 
1 
2 
NaN 
3 
NaN 

Тогда я могу сделать линейной интерполяции и получить что-то вроде этого

col2 
1 
2 
3 
3 
2 

Как я могу добиться этого?

ответ

5

UPDATE:

Есть ли способ, чтобы преобразовать данные обратно в исходную форму после интерполяции, т.е. вместо 1,2 или 3 у вас есть облачно, ветрено и дождливо снова?

Решение: Я намеренно добавил несколько строк к исходному DF:

In [129]: df 
Out[129]: 
    col1 col2 
0  5 cloudy 
1  3 windy 
2  6  NaN 
3  7 rainy 
4 10  NaN 
5  5 cloudy 
6 10  NaN 
7  7 rainy 

In [130]: df.dtypes 
Out[130]: 
col1  int64 
col2 category 
dtype: object 

In [131]: df.col2 = (df.col2.cat.codes.replace(-1, np.nan) 
    ...:    .interpolate().astype(int).astype('category') 
    ...:    .cat.rename_categories(df.col2.cat.categories)) 
    ...: 

In [132]: df 
Out[132]: 
    col1 col2 
0  5 cloudy 
1  3 windy 
2  6 rainy 
3  7 rainy 
4 10 cloudy 
5  5 cloudy 
6 10 cloudy 
7  7 rainy 

OLD "числовая" Ответ:

IIUC вы можете сделать это:

In [66]: df 
Out[66]: 
    col1 col2 
0  5 cloudy 
1  3 windy 
2  6  NaN 
3  7 rainy 
4 10  NaN 

сначала позвольте нам факторизовать col2:

In [67]: df.col2 = pd.factorize(df.col2, na_sentinel=-2)[0] + 1 

In [68]: df 
Out[68]: 
    col1 col2 
0  5  1 
1  3  2 
2  6 -1 
3  7  3 
4 10 -1 

теперь мы можем интерполировать его (замена -1 'S с NaN' ы):

In [69]: df.col2.replace(-1, np.nan).interpolate().astype(int) 
Out[69]: 
0 1 
1 2 
2 2 
3 3 
4 3 
Name: col2, dtype: int32 

тот же подход, но преобразование интерполированное серии в category DTYPE:

In [70]: df.col2.replace(-1, np.nan).interpolate().astype(int).astype('category') 
Out[70]: 
0 1 
1 2 
2 2 
3 3 
4 3 
Name: col2, dtype: category 
Categories (3, int64): [1, 2, 3] 
+0

Работает отлично. Есть ли способ преобразовать данные обратно в исходную форму после интерполяции, т. Е. Вместо 1,2 или 3 вы снова будете «облачно», «ветреный» и «дождливый»? –

+1

@WasswaSamuel, я обновил свой ответ - пожалуйста, проверьте – MaxU

+1

Его удивительный, сколько можно узнать, пройдя эти ответы. Сегодняшние принимают home factorize() и интерполируют() :) – Vaishali