ранга горячая кодировка python3 - PullRequest
0 голосов
/ 14 мая 2018

Я хочу обработать кадр данных pandas с ранговым кодированием вместо горячего кодирования.

Например, возьмем этот кадр данных pandas:

df = pd.DataFrame([[1,2],[3,2],[2,2]], columns=['colA', 'colB'])
print(df)
>>  colA  colB
0     1     2
1     3     0
2     2     3

Как это должно выглядеть вend:

print(df)
>> colA_0  colA_1  colA_2  colA_3  colB_0  colB_1  colB_2  colB_3
0    1       1       0       0       1        1       1      0
1    1       1       1       1       1        0       0      0
2    1       1       1       0       1        1       1      1

Это работало с небольшими фреймами данных:

def rankHotEncode(row):
    newFeatures = {}
    for i, v in row.iteritems():
        for k in range(MULTIPLYFEATURES):
            newFeatures[i + repr(k)] = 1 if v >= k else 0
    return pd.Series(newFeatures)

df.apply(rankHotEncode, axis=1)

Решение не должно быть жестко закодировано и эффективно для порядка ~ 100 000 строк.Как я могу улучшить предоставленное решение, чтобы сделать его более эффективным или как это лучше всего сделать?

1 Ответ

0 голосов
/ 14 мая 2018

Вы можете использовать scikit-learn oneHotEncoder с numpy.cumsum.Хотя он включает в себя несколько копий, он довольно эффективен, поскольку не работает с матрицей строка за строкой.Вот пример кода с его использованием.

from sklearn.preprocessing import OneHotEncoder
import pandas as pd
import numpy as np

df = pd.DataFrame([[1,2],[3,0],[2,3]], columns=['colA', 'colB'])
print(df)

n_values = df.max().values + 1
enc = OneHotEncoder(sparse=False, n_values=n_values, dtype=int)
enc.fit(df) 

encoded_columns = [
    '{}_{}'.format(col_name, i)
    for col_name, n_value in zip(df.columns, n_values)
    for i in range(n_value)
]

one_hot = enc.transform(df)
rank_hot = np.zeros_like(one_hot)

for col_start, col_end in zip(enc.feature_indices_[:-1], enc.feature_indices_[1:]):
    one_hot_col_reversed = one_hot[:, col_start: col_end][:, ::-1]
    rank_hot[:, col_start: col_end] = np.cumsum(one_hot_col_reversed, axis=1)[:, ::-1]

encoded_df = pd.DataFrame(rank_hot, columns=encoded_columns)

Это выводит для вашего примера

print(encoded_df)
>>    colA_0  colA_1  colA_2  colA_3  colB_0  colB_1  colB_2  colB_3
0       1       1       0       0       1       1       1       0
1       1       1       1       1       1       0       0       0
2       1       1       1       0       1       1       1       1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...