2016-06-05 5 views
1

У меня есть эта таблица в Excel:Как я могу сделать одну горячую кодировку с несколькими значениями в одной ячейке?

id class 
0 2 3 
1 1 3 
2 3 5 

Теперь я хочу сделать «специальное» один-горячее кодирование в Python. Для каждого идентификатора в первой таблице есть два числа. Каждое число соответствует классу (class1, class2 и т. Д.). Вторая таблица создается на основе первого, так что для каждого идентификатора каждый номер в своей строке отображается в соответствующем столбце класса, а остальные столбцы просто получают нули. Например, цифры для id 0 равны 2 и 3. 2 помещается в класс2, а 3 помещается в класс 3. Классы 1, 4 и 5 получают по умолчанию 0. Результат должен быть, как:

id class1 class2 class3 class4 class5 
0 0  2  3  0  0 
1 1  0  3  0  0 
2 0  0  3  0  5 

Моего предыдущим решения,

foo = lambda x: pd.Series([i for i in x.split()]) 
result=onehot['hotel'].apply(foo) 
result.columns=['class1','class2'] 
pd.get_dummies(result, prefix='class', columns=['class1','class2']) 

результатов в:

class_1 class_2 class_3 class_3 class_5 
    0 0.0  1.0 0.0  1.0 0.0 
    1 1.0  0.0 0.0  1.0 0.0 
    2 0.0  0.0 1.0  0.0 1.0 

(появляется class_3 дважды). Что я могу сделать, чтобы исправить это? (После этого шага я могу преобразовать его в окончательный формат, который я хочу.)

+1

@FengLi нужно всего лишь головы. Хранение 'lambda' функций, как вы сделали, побеждает их цель. Вместо этого вы можете просто использовать 'def'. – SvbZ3r0

ответ

3

Соответствует ли это вашей задаче?

#!/usr/bin/python 

input = [ 
    (0, (2,3)), 
    (1, (1,3)), 
    (2, (3,5)), 
] 

maximum = max(reduce(lambda x, y: x+list(y[1]), input, [])) 
# Or ... 
# maximum = 0 
# for i, classes in input: 
# maximum = max(maximum, *classes) 

# print header. 
print "\t".join(["id"] + ["class_%d" % i for i in range(1, 6)]) 

for i, classes in input: 
    print i, 
    for r in range(1, maximum+1): 
     print "\t", 
     if r in classes: 
      print float(r), 
     else: 
      print 0.0, 
    print 

Выход:

id  class_1 class_2 class_3 class_4 class_5 
0  0.0  2.0  3.0  0.0  0.0 
1  1.0  0.0  3.0  0.0  0.0 
2  0.0  0.0  3.0  0.0  5.0 
3

Это может быть проще разделить исходную dataframe на 3 колонки:

id class_a class_b 
0 2   3 
1 1   3 
2 3   5 

И затем выполнить нормальный один горячий кодирования на этом. После этого вы можете в конечном итоге с дубликатами столбцов, как:

id ... class_a_3 class_b_3 ... class_b_5 
0   0   1    0 
1   0   1    0 
2   1   0    0 

Но вы можете объединить/сумма тех, после факта довольно просто.

Кроме того, вы могли повернуть ту же логику и превратить ваш ФР в виде:

id class 
0 2 
0 3   
1 1 
1 3   
2 3 
2 5 

Тогда один горячий, что и агрегировать с помощью суммы по ключевому идентификатору.

4

Вы должны сделать ваши переменные быть categorical, а затем вы можете использовать one hot encoding как показано ниже:

In [18]: df1 = pd.DataFrame({"class":pd.Series(['2','1','3']).astype('category',categories=['1','2','3','4','5'])}) 

In [19]: df2 = pd.DataFrame({"class":pd.Series(['3','3','5']).astype('category',categories=['1','2','3','4','5'])}) 

In [20]: df_1 = pd.get_dummies(df1) 

In [21]: df_2 = pd.get_dummies(df2) 

In [22]: df_1.add(df_2).apply(lambda x: x * [i for i in range(1,len(df_1.columns)+1)], axis = 1).astype(int).rename_axis('id') 
Out[22]: 
    class_1 class_2 class_3 class_4 class_5 
id            
0   0  2  3  0  0 
1   1  0  3  0  0 
2   0  0  3  0  5