sklearn Pipeline中FunctionTransformer指定列生成新列报错处理
报错根因
FunctionTransformer的第二个位置参数是用于传入逆变换逻辑的inverse_func,要求传入可调用对象。你的代码把列名字符串'X2'传到了这个参数位,框架执行时尝试调用该字符串作为函数,就触发了TypeError: 'str' object is not callable。
另外FunctionTransformer本身不支持直接指定要处理的列名,默认会对输入的全部数据应用传入的变换函数,因此就算参数位置传对,也无法实现「仅对X2、X3列计算、生成新列且保留原列」的需求。
实现方案
根据流水线复杂度不同,可以选以下两种实现方式:
方案1:直接编写适配全DataFrame的变换函数(适合简单特征衍生场景)
直接在自定义函数中完成列提取、计算、新列拼接全流程,FunctionTransformer直接调用该函数即可,逻辑简单直观。
import pandas as pd from sklearn.pipeline import Pipeline from sklearn.preprocessing import FunctionTransformer # 示例数据集 df = pd.DataFrame(columns=['X1', 'X2', 'X3'], data=[ [1,16,9], [4,36,16], [1,16,9], [2,9,8], [3,36,15], [2,49,16], [4,25,14], [5,36,17]]) # 自定义特征生成函数:输入完整DataFrame,返回带新互补列的DataFrame def gen_comp_feat(X): X = X.copy() # 拷贝避免修改原始数据 X['X2_comp'] = 100 - X['X2'] X['X3_comp'] = 100 - X['X3'] return X # 构建流水线 pipe = Pipeline([ ('add_comp_feat', FunctionTransformer(gen_comp_feat, validate=False)) ]) # 执行变换 result = pipe.fit_transform(df)
运行后输出结果会保留原始的X1、X2、X3列,同时新增X2_comp、X3_comp两个互补列。
方案2:配合ColumnTransformer做列选择(适合复杂多步变换流水线)
如果后续流水线还要对不同列组做差异化处理(比如数值列标准化、分类列编码),用ColumnTransformer做列路由更规范,注意设置remainder='passthrough'保留未被处理的原始列,避免数据丢失。
from sklearn.compose import ColumnTransformer # 自定义变换逻辑:输入选中的X2、X3子表,返回新生成的互补列 def comp_calc(X_sub): res = pd.DataFrame() res['X2_comp'] = 100 - X_sub['X2'] res['X3_comp'] = 100 - X_sub['X3'] return res # 构建列变换器 col_trans = ColumnTransformer( transformers=[ ('gen_comp', FunctionTransformer(comp_calc, validate=False), ['X2', 'X3']) ], remainder='passthrough', # 保留其余未指定处理的原始列 verbose_feature_names_out=False # 关闭自动前缀,保持列名简洁 ) # 构建流水线 pipe = Pipeline([ ('add_comp_feat', col_trans) ]) # 执行变换,可转为DataFrame查看 result = pipe.fit_transform(df) result_df = pd.DataFrame(result, columns=pipe.get_feature_names_out())
内容的提问来源于stack exchange,提问作者Manu Sharma
相关产品推荐
相关产品推荐

