У меня есть ситуация, когда мне нужно выполнить некоторую обработку столбца c в конвейере, но поскольку преобразователи возвращают массивы numpy, а не pandas фреймы данных, у меня нет имен столбцов для выполнения моей функции engineering.
Вот простой, воспроизводимый пример, где у меня есть функция с именем engineer_feature
, которую я хочу использовать для создания новых данных. Мне нужно использовать его во время / после конвейера, потому что это зависит от вменения одного столбца, и я хотел бы, чтобы он мог выполняться во время перекрестной проверки в k-кратном размере.
import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import FunctionTransformer, OneHotEncoder, StandardScaler
df = pd.DataFrame({"Type": ["Beta", "Beta", "Alpha", "Charlie", "Beta", "Charlie"], "A": [1, 2, 3, np.nan, 22, 4], "B": [5, 7, 12, 21, 12, 10]})
def engineer_feature(df):
df["C"] = df["A"] / df["B"]
return df
categorical_transformer = Pipeline([
("one_hot", OneHotEncoder())
])
numeric_transformer = Pipeline([
("imputer", SimpleImputer()),
("engineer", FunctionTransformer(engineer_feature)),
("scaler", StandardScaler())
])
preprocessor = ColumnTransformer([
("categorical", categorical_transformer, ["Type"]),
("numeric", numeric_transformer, ["A", "B"])
])
preprocessor.fit_transform(df)
Что приводит к этому ошибка:
IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices
Это имеет смысл, потому что engineer_feature
пытается индексировать столбцы, как если бы они были фреймами данных, когда они просто numpy массивы.
Какова стратегия обхода это? Я не хочу жестко кодировать индексы столбцов для доступа к ним через numpy, тем более что в моем реальном кадре данных есть еще много столбцов.