Я пытаюсь предварительно обработать набор данных для использования в XGBoost, сопоставив классы в каждом столбце с числовыми значениями. Рабочий пример выглядит следующим образом:
from collections import defaultdict
from sklearn.preprocessing import LabelEncoder
import pandas as pd
df1 = pd.DataFrame(data = {'col1': ['A', 'B','C','B','A'], 'col2': ['Z', 'X','Z','Z','Y'], 'col3':['I','J','I','J','J']})
d = defaultdict(LabelEncoder)
encodedDF = df1.apply(lambda x: d[x.name].fit_transform(x))
inv = encodedDF.apply(lambda x: d[x.name].inverse_transform(x))
Где encodedDF выдает результат:
col1 col2 col3
0 2 0
1 0 1
2 2 0
1 2 1
0 1 1
И inv просто возвращает его обратно в исходный кадр данных. Моя проблема в том, что когда вводятся нулевые значения:
df2 = pd.DataFrame(data = {'col1': ['A', 'B',None,'B','A'], 'col2': ['Z', 'X','Z',None,'Y'], 'col3':['I','J','I','J','J']})
encodedDF = df2.apply(lambda x: d[x.name].fit_transform(x))
Выполнение выше приведёт к ошибке:
"TypeError: ('аргумент должен быть строкой или числом', 'произошел в индексе col1 ') "
По сути, я хочу применить кодировку, но пропустите значения отдельных ячеек, которые являются нулевыми, чтобы получить такой вывод:
col1 col2 col3
0 2 0
1 0 1
NaN 2 0
1 NaN 1
0 1 1
Я не могу использовать dropna () перед применением кодировки, потому что тогда я теряю данные, которые буду пытаться вписать в XBSoost. Я не могу использовать условные выражения для пропуска x, если он нулевой (например, с помощью x.notnull () в лямбда-функции), потому что fit_transform (x) использует объект Pandas .Series в качестве аргумента и ни один из логических операторов, которые я можно использовать в условном виде, чтобы делать то, что я пытаюсь сделать. Я не уверен, что еще можно попробовать, чтобы заставить это работать. Я надеюсь, что то, что я пытаюсь сделать, имеет смысл. Дайте мне знать, если мне нужно уточнить.