Использование Scikit StandardScaler в конвейере для подмножества столбцов фрейма данных Pandas

Я хочу использовать sklearn.предварительная обработка.StandardScaler для подмножества столбцов фрейма данных pandas. Вне конвейера это тривиально:

df[['A', 'B']] = scaler.fit_transform(df[['A', 'B']])

но теперь предположим, что у меня есть столбец " C " в DF типа string и следующее определение конвейера

from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

pipeline =  Pipeline([
                ('standard', StandardScaler())
            ])

df_scaled = pipeline.fit_transform(df)

как я могу сказать StandardScaler только масштабировать столбцы A и B?

Я привык к конвейерам SparkML, где масштабируемые объекты могут быть переданы конструктору масштабатора компонент:

normalizer = Normalizer(inputCol="features", outputCol="features_norm", p=1.0)

Примечание: столбец объектов содержит разреженный вектор со всеми числовыми столбцами объектов, созданными VectorAssembler

2 ответов


в direct sklearn вам нужно будет использовать FunctionTransformer вместе с FeatureUnion. То есть, ваш трубопровод будет выглядеть так:

pipeline =  Pipeline([
            ('scale_sum', feature_union(...))
        ])

где внутри объединения объектов одна функция применит стандартный масштабатор к некоторым столбцам, а другая передаст другие столбцы нетронутыми.


используя Козероги (который я написал в точности, чтобы сделать sklearn и панды работают лучше), вы могли бы написать это как следует:

from ibex.sklearn.preprocessing import StandardScaler
from ibex import trans

pipeline = (trans(StandardScaler(), in_cols=['A', 'B']) + trans(None, ['c', 'd'])) | <other pipeline steps>

Вы можете проверить sklearn-панды который предлагает интеграцию Pandas DataFrame и sklearn, например, с DataFrameMapper:

mapper = DataFrameMapper([
...     (list_of_columnnames, StandardScaler())
... ])

I Если вам не нужны внешние зависимости, вы можете использовать простой собственный трансформатор, как я ответил здесь:

class Columns(BaseEstimator, TransformerMixin):
    def __init__(self, names=None):
        self.names = names

    def fit(self, X, y=None, **fit_params):
        return self

    def transform(self, X):
        return X[self.names]

pipe =  make_pipeline(Columns(names=list_of_columnnames),StandardScaler())