Source code for evalml.pipelines.components.transformers.encoders.onehot_encoder


import numpy as np
import pandas as pd

from .encoder import CategoricalEncoder


[docs]class OneHotEncoder(CategoricalEncoder): """One-hot encoder to encode non-numeric data""" name = 'One Hot Encoder' hyperparameter_ranges = {}
[docs] def __init__(self, top_n=10, random_state=0): """Initalizes self.""" parameters = {"top_n": top_n} super().__init__(parameters=parameters, component_obj=None, random_state=random_state)
def _get_cat_cols(self, X): """Get names of 'object' or 'categorical' columns in the DataFrame.""" obj_cols = [] for idx, dtype in enumerate(X.dtypes): if dtype == np.object or pd.api.types.is_categorical_dtype(dtype): obj_cols.append(X.columns.values[idx]) return obj_cols
[docs] def fit(self, X, y=None): top_n = self.parameters['top_n'] if not isinstance(X, pd.DataFrame): X = pd.DataFrame(X) X_t = X cols_to_encode = self._get_cat_cols(X_t) self.col_unique_values = {} for col in X_t.columns: if col in cols_to_encode: value_counts = X_t[col].value_counts(dropna=False).to_frame() if len(value_counts) <= top_n: unique_values = value_counts.index.tolist() else: value_counts = value_counts.sample(frac=1, random_state=self.random_state) value_counts = value_counts.sort_values([col], ascending=False, kind='mergesort') unique_values = value_counts.head(top_n).index.tolist() self.col_unique_values[col] = unique_values return self
[docs] def transform(self, X, y=None): """One-hot encode the input DataFrame. Arguments: X (pd.DataFrame): Dataframe of features. y (pd.Series): Ignored. Returns: Transformed dataframe, where each categorical feature has been encoded into numerical columns using one-hot encoding. """ try: col_values = self.col_unique_values except AttributeError: raise RuntimeError("You must fit one hot encoder before calling transform!") if not isinstance(X, pd.DataFrame): X = pd.DataFrame(X) X_t = pd.DataFrame() for col in X.columns: if col in col_values: unique = col_values[col] for label in unique: new_name = str(col) + "_" + str(label) add = (X[col] == label).astype("uint8") add = add.rename(new_name) X_t = pd.concat([X_t, add], axis=1) else: X_t = pd.concat([X_t, X[col]], axis=1) return X_t