Кодируйте символьные столбцы как порядковые, но сохраняйте числовые столбцы одинаковыми - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть фрейм данных, подобный следующему:

test = {"viral": "pos", "Status": "positive", "Age": 59, "score": 5}
test2 = {"viral": "neg"}
df = pd.DataFrame.from_dict([test, test2])

Я хочу закодировать символьные столбцы (вирусные, Status) в виде порядковых чисел, но оставить только числовые значения.Требуемый вывод - это пустой массив с одинаковыми именами столбцов.

Если я использую OrdinalEncoder из sklearn, он не работает со значениями NaN.Даже если бы не было значений NaN, он все равно будет порядковым образом кодировать числовые столбцы.Я хочу заполнить значения NaN 0 в символьных столбцах, но сохранить NaN в числовых столбцах.

Какой самый простой способ сделать это?

Желаемый вывод (в массиве numpy):

    Age    Status  score viral
0  59.0         1    5.0     1
1   NaN         0    NaN     0

Спасибо!Джек

РЕДАКТИРОВАТЬ: Я также хотел бы, чтобы преобразование из закодированного значения в исходное значение, например {i: dict(enumerate(v)) for i, v in enumerate(enc.categories_)} при использовании enc=OrdinalEncoder() (см. Векторизация двумерного массива символов по столбцам )

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Использование LabelEncoder

enc = sklearn.preprocessing.LabelEncoder()

mask = df.dtypes.eq(np.object)
df.loc[:, mask] = df.loc[:, mask].astype(str).apply(enc.fit_transform)

Для того, чтобы вы могли inverse_transform, вы можете создать использование defaultdict изLabelEncoders.key - ваш выбор.Я бы предложил использовать имя столбца: интуитивно понятное и простое

from collections import defaultdict
enc = defaultdict(sklearn.preprocessing.LabelEncoder)

mask = df.dtypes.eq(np.object)
df.loc[:, mask] = df.loc[:, mask].astype(str).apply(lambda s: enc[s.name].fit_transform(s))

    Status  viral
0   1       1
1   0       0

К inverse_transform

df.loc[:, mask].apply(lambda s: enc[s.name].inverse_transform(s))

    Status      viral
0   positive    pos
1   NaN         neg
0 голосов
/ 14 ноября 2018

Обновление, когда есть NaN, он будет кодировать как -1, если вам нужен NaN, вы можете конвертировать обратно, используя replace

df=pd.DataFrame([test,test2])
df.dtypes
Out[152]:
Age       float64
Status     object
score     float64
viral      object
dtype: object
listc=df.columns[df.dtypes=='object']

for x in listc:
    df[x]=df[x].astype('category').cat.codes

df
Out[156]: 
    Age  Status  score  viral
0  59.0       0    5.0      1
1   NaN      -1    NaN      0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...