使用DataFrameMapper结合PolynomialFeatures时的维度错误及KeyError问题
我来帮你排查这个问题,这其实是sklearn_pandas.DataFrameMapper和PolynomialFeatures对输入维度要求不匹配导致的,咱们一步步拆解解决:
问题根源分析
ValueError:期望2D数组却得到1D数组
当你在DataFrameMapper中用字符串指定单个列(比如'houseAge_income')时,mapper会把该列提取为1D的Series/数组,但PolynomialFeatures的fit_transform方法要求输入必须是2D数组(形状为(n_samples, n_features)),这就触发了维度不匹配的错误。KeyError:使用reshape后的报错
你尝试写houseAge_income.reshape(-1,1)是不符合DataFrameMapper语法的——mapper的第一个参数是列选择器,只能是列名字符串或列名列表,不能直接对数组进行操作,所以mapper会把这个表达式当成列名去查找,自然找不到对应的列,触发KeyError。
两种正确的解决方案
方案1:用列表包裹单个列(最简单)
DataFrameMapper对列表形式的列选择器(哪怕只有一个列),会返回2D数组(形状(n_samples, 1)),刚好满足PolynomialFeatures的输入要求。直接修改你的mapper定义即可:
from sklearn_pandas import DataFrameMapper from sklearn.preprocessing import PolynomialFeatures import pandas as pd # 假设你的数据集已经生成了houseAge_income列 data = pd.read_csv("your_house_data.csv") data['houseAge_income'] = data['housing_median_age'] * data['median_income'] # 正确配置DataFrameMapper mapper = DataFrameMapper([ # 用列表包裹单个列,输出2D数组供PolynomialFeatures处理 (['houseAge_income'], PolynomialFeatures(degree=2, include_bias=False)), (['median_income'], PolynomialFeatures(degree=2, include_bias=False)), # 其余列保留原特征,用字符串或列表都可以 ('housing_median_age', None), ('total_rooms', None), # ... 其他需要保留的列 ]) # 执行fit_transform不再报错 processed_data = mapper.fit_transform(data)
注意:
include_bias=False是为了避免生成重复的全1偏置列(如果多个特征都加偏置,会导致冗余),如果需要偏置项,可以去掉这个参数。
方案2:用FunctionTransformer转换维度(更灵活)
如果需要更灵活的维度转换操作,可以结合sklearn.preprocessing.FunctionTransformer把1D数组转成2D,再和PolynomialFeatures组成管道:
from sklearn.preprocessing import FunctionTransformer mapper = DataFrameMapper([ # 先把1D列转成2D,再应用多项式特征 ('houseAge_income', FunctionTransformer(lambda x: x.reshape(-1, 1), validate=False) + PolynomialFeatures(degree=2, include_bias=False)), ('median_income', FunctionTransformer(lambda x: x.reshape(-1, 1), validate=False) + PolynomialFeatures(degree=2, include_bias=False)), # 其余列保留原特征 ('housing_median_age', None), # ... 其他列 ]) processed_data = mapper.fit_transform(data)
这个方案适合需要对列做更多自定义转换的场景,不过方案1已经能解决你的问题,更简洁。
总结
- 避免用字符串单独指定列,改用列表包裹单个列,让
DataFrameMapper输出2D数组; - 不要在列选择器里直接写数组操作,那不是
DataFrameMapper的正确用法。
内容的提问来源于stack exchange,提问作者Dr Nisha Arora

