Есть ли умный способ применить порядковый кодировщик (на основе разных категорий) для нескольких переменных? - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть несколько переменных с текстовыми значениями, которые я хочу преобразовать в числа c с помощью порядкового кодировщика. Но эти переменные следуют различным порядковым логикам c. Например:

import pandas as pd
import numpy as np
d = {"attr1":["Excellent", "Fair", "Fair", "Good", "Poor"],
     "attr4":["Fair", "Good", "Good", "Excellent", "Excellent"],
     "attr2":["Finished", "Unfinished", "Partially Finished", "Finished", "Unfinished"],
     "attr3":["Satisfied", "Unsatisfied", "Unsatisfied", "Satisfied", "Satisfied"]}
data = pd.DataFrame(data = d)

Вы можете заметить, что «attr1» и «attr4» имеют одинаковые уникальные значения. Чтобы преобразовать текстовые значения в цифры c:

from sklearn.preprocessing import OrdinalEncoder
# Assign attributes to different lists based on the values
attr_list1 = ["attr1", "attr4"]
attr_list2 = ["attr2"]
attr_list3 = ["attr3"]

# Create categories to instruct how ordinal encoder should work
cat1 = ["Poor", "Fair", "Good", "Excellent"]
cat2 = ["Unfinished", "Partially Finished", "Finished"]
cat3 = ["Unsatisfied", "Satisfied"]

# Initialize the encoder
encoder1 = OrdinalEncoder(categories = [cat1])
encoder2 = OrdinalEncoder(categories = [cat2])
encoder3 = OrdinalEncoder(categories = [cat3])

def ord_encode(attr_list, encoder):
    for attr in attr_list:
        data[attr] = encoder.fit_transform(data[[attr]])
    return data

data = ord_encode(attr_list1, encoder1)
data = ord_encode(attr_list2, encoder2)
data = ord_encode(attr_list3, encoder3)

, я считаю свое решение очень неэффективным и неудобным. Представьте, что у меня более 20 атрибутов с 4 или 5 различными категориями. Мне интересно, есть ли какой-нибудь умный способ решить мою проблему?

Спасибо.

1 Ответ

0 голосов
/ 18 апреля 2020

sklearn-pandas можно использовать, чтобы быстро сделать это для вас. Я бы построил отображение столбца на категорию, а затем использовал бы DataFrameMapper для создания конвейера для меня.

column_to_cat = {
    "attr1": cat1,
    "attr4": cat1,
    "attr2": cat2,
    "attr3": cat3
}

mapper_df = DataFrameMapper(
    [
        ([col], OrdinalEncoder(categories = [cat])) for col, cat in column_to_cat.items()
    ],
    df_out=True
)
mapper_df.fit_transform(data.copy())

Полный код:

import pandas as pd
import numpy as np
from sklearn_pandas import DataFrameMapper
from sklearn.preprocessing import OrdinalEncoder
d = {"attr1":["Excellent", "Fair", "Fair", "Good", "Poor"],
     "attr4":["Fair", "Good", "Good", "Excellent", "Excellent"],
     "attr2":["Finished", "Unfinished", "Partially Finished", "Finished", "Unfinished"],
     "attr3":["Satisfied", "Unsatisfied", "Unsatisfied", "Satisfied", "Satisfied"]}
data = pd.DataFrame(data = d)

# Create categories to instruct how ordinal encoder should work
cat1 = ["Poor", "Fair", "Good", "Excellent"]
cat2 = ["Unfinished", "Partially Finished", "Finished"]
cat3 = ["Unsatisfied", "Satisfied"]

# Assign attributes to different lists based on the values
column_to_cat = {
    "attr1": cat1,
    "attr4": cat1,
    "attr2": cat2,
    "attr3": cat3
}


mapper_df = DataFrameMapper(
    [
        ([col], OrdinalEncoder(categories = [cat])) for col, cat in column_to_cat.items()
    ],
    df_out=True
)
mapper_df.fit_transform(data.copy())
...