Tengo el siguiente conjunto de datos de juguetes.

import random
import numpy as np
import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.base import TransformerMixin, BaseEstimator
from sklearn.pipeline import Pipeline
from sklearn.compose import make_column_selector as selector
K = 6
tar = random.choices([1, 0], weights=[0.2, 0.8], k=K)
cat = random.choices(["A", "B", "C"], k=K)
dog = random.choices(["D", "E", "F"], k=K)
n1 = [random.randint(1,9) for _ in range(K)]
n2 = [random.randint(1,9) for _ in range(K)]
df = pd.DataFrame.from_dict({"tar": tar, "cat": cat, 'dog': dog, 'n1': n1})

Ejecuto el siguiente código:

class CategoricalFeaturesSelector(BaseEstimator, TransformerMixin):
    def fit(self, X, y=None):
        return self
    def transform(self, X):
        return X.loc[:, X.select_dtypes(include=['int64', 'float64']).columns.tolist()]


tr3 = Pipeline([
    ('selector3', CategoricalFeaturesSelector())
])
tr3.fit_transform(df)

Que devuelve la salida en un formato DataFrame como esperaba.

enter image description here

Pero cuando reviso el código un poco como sigue. Devuelve un ndarray numpy en lugar de un objeto Pandas DataFrame, aunque lo he especificado explícitamente en la definición de transform.

from sklearn.compose import make_column_selector as selector
class dummyTransformer(BaseEstimator, TransformerMixin):
    def fit(self, X, y=None):
        return self
    def transform(self, X):
        return pd.DataFrame(X, columns=selector(dtype_include='object')(X)) 


tr4 = ColumnTransformer(transformers=[
    ('dum', dummyTransformer(), selector(dtype_include='object'))
])
tr4.fit_transform(df)

enter image description here

¿Alguien puede decirme qué causa la diferencia? Quiero que devuelva un objeto DataFrame en lugar de un ndarray numpy.

2
Li-Pin Juan 14 mar. 2021 a las 21:19

1 respuesta

La mejor respuesta

Pipeline devolverá el resultado del método transform() de CategoricalFeaturesSelector

return last_step.fit(Xt, y,**fit_params_last_step).transform(Xt)

Mientras que ColumnTransformer apila horizontalmente los resultados de los transformadores. Puede verificar esto en el código fuente

return self._hstack(list(Xs))

Que llama a np.stack() en el parámetro de entrada list(Xs)

0
Miguel Trejo 14 mar. 2021 a las 19:17