使用make_column_selector选择分类列时触发TypeError: unhashable type: 'list'错误
使用make_column_selector选择分类列时触发TypeError: unhashable type: 'list'错误
我完全懂你现在的困扰——做BigMart销售预测的数据预处理时,用make_column_selector处理数值列顺风顺水,轮到分类列就突然抛出TypeError: unhashable type: 'list',确实挺闹心的。结合你给出的代码片段和报错情况,我来帮你捋捋常见的问题点和解决办法:
最可能的两个错误原因及修复方案
1. 定义分类选择器时传入了嵌套列表
很多时候这个报错是因为给dtype_include参数传了嵌套列表(比如[[object]]),而不是一维列表或者单个类型字符串。make_column_selector内部需要哈希这些类型参数,嵌套列表是不可哈希的,所以会触发错误。
❌ 错误示例:
# 别这么写!嵌套列表会导致unhashable错误 cat_selector = make_column_selector(dtype_include=[['object']])
✅ 正确写法:
from sklearn.compose import make_column_selector # 方式1:单个类型字符串 cat_selector = make_column_selector(dtype_include='object') # 方式2:包含多种分类类型的一维列表 cat_selector = make_column_selector(dtype_include=['object', 'category'])
2. 错误地直接用选择器函数索引数据
make_column_selector返回的是一个选择器函数,不是直接的列名列表。如果你直接写X_train[cat_selector],Python会把这个函数当成索引对象,内部处理时就会触发哈希错误。
❌ 错误示例:
# 别这么写!直接用选择器函数索引会报错 X_train_cat = X_train[cat_selector]
✅ 正确写法:
先调用选择器函数获取列名列表,再用列表索引数据:
# 先获取分类列的名称列表 cat_cols = cat_selector(X_train) # 再用列表索引数据 X_train_cat = X_train[cat_cols]
结合你的Pipeline场景优化写法
如果是要配合ColumnTransformer做不同列的编码处理,其实不需要手动调用选择器,直接把选择器函数传入ColumnTransformer即可,它会自动帮你处理列选择:
from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder, StandardScaler from sklearn.model_selection import train_test_split # 你的原有代码 seed = 200 X = bigmart_copy.drop('Item_Outlet_Sales', axis = 1) y = bigmart_copy.Item_Outlet_Sales X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.3, shuffle = True, random_state=seed) # 定义选择器 num_selector = make_column_selector(dtype_include=['int64', 'float64']) cat_selector = make_column_selector(dtype_include=['object', 'category']) # 构建预处理管道 preprocessor = ColumnTransformer( transformers=[ ('num_scaler', StandardScaler(), num_selector), ('cat_encoder', OneHotEncoder(sparse_output=False), cat_selector) ]) # 拟合并转换训练数据 X_train_processed = preprocessor.fit_transform(X_train)
这样写既简洁又能避免手动索引带来的错误,完美适配你的销售预测预处理场景~
备注:内容来源于stack exchange,提问作者SirTee12
相关产品推荐
相关产品推荐

