Горячее кодирование кадра данных pandas с использованием словаря с именем и значениями столбца - PullRequest
0 голосов
/ 05 ноября 2019

В настоящее время у меня есть приведенный ниже код для горячего кодирования информационного кадра pandas с использованием словаря, в котором ключи - это имена элементов, а значения - это список значений для функции.

def dummy_encode_dataframe(self, df, dummy_values_dict):
    for (feature, dummy_values) in sorted(dummy_values_dict.items()):
        for dummy_value in sorted(dummy_values):
            dummy_name = u'%s_%s' % (feature, dummy_value)
            df[dummy_name] = (df[feature] == dummy_value).astype(float)
        del df[feature]
    return df

dummy_values_dict имеетструктура:

feature name (key)   list of possible values (strings)
---------            ---------------------------------
F1                   ['A', 'B', 'C', 'MISSING']
F2                   ['D', 'E', 'F', 'MISSING']
F3                   ['G', 'H', 'I']

с образцом ввода / вывода:

df (one row):
====
F1     F2    F3
---  -----  -----  
'A'    'Q'   'H'

ожидаемый результат:

df_output:
====
F1_A  F1_B  F1_C  F1_MISSING F2_D  F2_E  F2_F F2_MISSING F3_G  F3_H  F3_I
---   ----  -----  --------- ----  ----  ---- ---------- ----  ----  -----
 1      0     0       0        0    0     0        0       0     1    0

Проблема в том, что цикл for занимает слишком много времени длязапустить. Есть ли способ оптимизировать его?

ОБНОВЛЕНИЕ 1: Из комментария об использовании OneHotEncoder в scikit-learn ... Можете ли вы уточнить этот фрагмент кода, чтобы получить желаемый результат?

import pandas as pd 
df = pd.DataFrame(columns=['F1', 'F2', 'F3']) 
df.loc[0] = ['A', 'Q', 'H'] 
dummy_values_dict = { 'F1': ['A', 'B', 'C', 'MISSING'], 'F2': ['D', 'E', 'F', 'MISSING'], 'F3': ['G', 'H', 'I'] } 
# import OneHotEncoder 
from sklearn.preprocessing import OneHotEncoder 
categorical_cols = sorted(dummy_values_dict.keys()) 
# instantiate OneHotEncoder 
# todo: encoding...

Ответы [ 2 ]

0 голосов
/ 06 ноября 2019

pd.get_dummies должно работать в вашем случае, но сначала нам нужно установить все значения, отсутствующие в словаре, на NaN

df = pd.DataFrame({'F1': ['A', 'B', 'C', 'MISSING'], 'F2': [
                  'Q', 'E', 'F', 'MISSING'], 'F3': ['G', 'H', 'I', 5]})
#         F1       F2 F3
# 0        A        Q  G
# 1        B        E  H
# 2        C        F  I
# 3  MISSING  MISSING  5

dummy_values_dict = {'F1': ['A', 'B', 'C', 'MISSING'], 'F2': [
    'D', 'E', 'F', 'MISSING'], 'F3': ['G', 'H', 'I']}

Мы можем установить все остальные значения на np.nan:

for col in df.columns:
    df.loc[~df[col].isin(dummy_values_dict[col]), col] = np.nan
print(df)
#         F1       F2   F3
# 0        A      NaN    G
# 1        B        E    H
# 2        C        F    I
# 3  MISSING  MISSING  NaN

Тогда мы можем использовать pd.get_dummies для выполнения работы:

print(pd.get_dummies(df))
#    F1_A  F1_B  F1_C  F1_MISSING  F2_E  F2_F  F2_MISSING  F3_G  F3_H  F3_I
# 0     1     0     0           0     0     0           0     1     0     0
# 1     0     1     0           0     1     0           0     0     1     0
# 2     0     0     1           0     0     1           0     0     0     1
# 3     0     0     0           1     0     0           1     0     0     0

Имейте в виду, что если у нас нет одного значения (например, 'D' в столбцах 'F2'), столбец' F2_D 'не будет, но это легко исправить, если вам нужен этот столбец.

0 голосов
/ 06 ноября 2019

Может быть, вопрос не был хорошо сформулирован. Мне удалось найти более оптимизированную реализацию (возможно, есть и лучшую), используя следующий код:

    import pandas as pd
    import numpy as np


    def dummy_encode_dataframe_optimized(df, dummy_values_dict):

        column_headers = np.concatenate(np.array(
            [np.array([k + '_value_' + s
                       for s in sorted(dummy_values_dict[k])]) 
                       for k in sorted(dummy_values_dict.keys())]), axis=0)

        feature_values = [str(feature) + '_value_' + str(df[feature][0])
                          for feature in dummy_values_dict.keys()]

        one_hot_encode_vector = np.vectorize(lambda x: float(1) if x in feature_values else float(0))(column_headers)

        untouched_df = df.drop(df.ix[:, dummy_values_dict.keys()].head(0).columns, axis=1)

        hot_encoded_df = pd.concat(
            [
                untouched_df,
                pd.DataFrame(
                    [one_hot_encode_vector],
                    index=untouched_df.index,
                    columns=column_headers
                )
            ], axis=1
        )

        return hot_encoded_df


    df = pd.DataFrame(columns=['F1', 'F2', 'F3'])
    df.loc[0] = ['A', 'Q', 'H']
    dummy_values_dict = { 'F1': ['A', 'B', 'C', 'MISSING'], 'F2': ['D', 'E', 'F', 'MISSING'], 'F3': ['G', 'H', 'I'] }

    result = dummy_encode_dataframe_optimized(df, dummy_values_dict)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...