Scikit-learn中make_column_transformer管道报错:数组无columns属性
问题解决:Scikit-learn管道中numpy数组转DataFrame的报错处理
你的推测完全正确——make_column_transformer默认输出numpy数组,后续步骤如果依赖列名字符串指定字段,就会因为数组没有columns属性触发报错。不用拆分管道,有几种更优的解决方式:
1. 让ColumnTransformer直接输出DataFrame(推荐)
从Scikit-learn 0.23版本开始,make_column_transformer支持transform_output='pandas'参数,直接输出带列名的DataFrame,后续步骤可以正常使用列名字符串:
from sklearn.compose import make_column_transformer from sklearn.preprocessing import StandardScaler, OneHotEncoder # 定义预处理步骤,指定输出为DataFrame preprocessor = make_column_transformer( (StandardScaler(), ['age', 'income']), # 数值列标准化 (OneHotEncoder(), ['gender', 'city']), # 分类列独热编码 transform_output='pandas' # 关键参数:输出Pandas DataFrame )
之后把这个preprocessor加入make_pipeline,后续所有步骤拿到的都是带列名的DataFrame,不会再触发列名相关报错。
2. 手动实现数组转DataFrame转换器(兼容老版本Scikit-learn)
如果你的Scikit-learn版本低于0.23,可以自定义一个简单的转换器,把numpy数组转回DataFrame:
from sklearn.base import BaseEstimator, TransformerMixin import pandas as pd class ArrayToDataFrame(BaseEstimator, TransformerMixin): def __init__(self, columns): self.columns = columns def fit(self, X, y=None): return self def transform(self, X): return pd.DataFrame(X, columns=self.columns)
然后把它加到管道中ColumnTransformer的后面:
from sklearn.pipeline import make_pipeline # 先定义不带transform_output的预处理 preprocessor = make_column_transformer( (StandardScaler(), ['age', 'income']), (OneHotEncoder(), ['gender', 'city']) ) # 串联管道:预处理 → 转DataFrame → 后续步骤 pipe = make_pipeline( preprocessor, ArrayToDataFrame(columns=preprocessor.get_feature_names_out()), # 这里加后续需要列名的转换步骤 )
3. 改用列索引指定字段(不推荐)
如果不想转DataFrame,也可以把后续步骤中的列名字符串改成数组的索引位置(比如原来的['age']改成[0]),但这种方式维护性差,一旦列顺序变化就会出错,仅适合固定列顺序的简单场景。
内容的提问来源于stack exchange,提问作者HARSHAL RATHORE
相关产品推荐
相关产品推荐

