使用sklearn OneHotEncoder转字符串为变量时遇类型错误求助
问题描述
需要使用OneHotEncoder将数据的第2、3列(如性别、地点这类字符串字段)转换为二进制编码,修改导师提供的代码后运行出现以下错误:
TypeError:Encoders require their input to be uniformly strings or numbers. Got ['float', 'str']
当前代码如下:
import numpy as np import matplotlib.pyplot as plt import pandas as pd from sklearn.preprocessing import OneHotEncoder spreadsheet = pd.read_csv('/Users/davidforsythe/Downloads/diagnose3.csv') X = spreadsheet.iloc[:, 1:14].values y = spreadsheet.iloc[:, -1].values encoder = OneHotEncoder() X2 = X[:,1:3].reshape(-1,1) X3 = encoder.fit_transform(X2).toarray() X = np.concatenate((X3,X[:,0:3]),axis=1) X = X[:, 1:] print(spreadsheet.iloc[:, 1:3])
错误原因
- 类型混合问题:待处理的第2、3列存在字符串与浮点数混合的情况,大概率是列中存在缺失值,pandas自动将列类型转为
float,但仍保留字符串值,导致类型不统一。 - 错误的reshape操作:
X[:,1:3]是2列数据,用reshape(-1,1)将其压缩为1列,打乱了原有列结构的同时,让不同类型数据混在同一列,触发OneHotEncoder的类型检查机制。 - 数据合并逻辑混乱:后续合并编码结果与原数据的代码存在索引错误,会导致重复包含原列或数据结构混乱。
解决方案
以下是修正后的代码,解决了类型统一和编码逻辑问题:
import numpy as np import pandas as pd from sklearn.preprocessing import OneHotEncoder # 加载数据 spreadsheet = pd.read_csv('/Users/davidforsythe/Downloads/diagnose3.csv') # 提取特征与目标变量,用DataFrame更便于类型处理 X = spreadsheet.iloc[:, 1:14] y = spreadsheet.iloc[:, -1].values # 定位需要编码的第2、3列(对应DataFrame索引1和2) cols_to_encode = [1, 2] # 将待编码列强制转为字符串类型,统一数据类型 X[X.columns[cols_to_encode]] = X[X.columns[cols_to_encode]].astype(str) # 初始化编码器,设置handle_unknown='ignore'避免训练集外类别报错 encoder = OneHotEncoder(sparse_output=False, handle_unknown='ignore') # 对指定列执行编码 encoded_cols = encoder.fit_transform(X.iloc[:, cols_to_encode]) # 获取编码后的列名 encoded_col_names = encoder.get_feature_names_out(X.columns[cols_to_encode]) # 将编码结果转为DataFrame encoded_df = pd.DataFrame(encoded_cols, columns=encoded_col_names) # 合并编码列与原数据(剔除原待编码列) X_processed = pd.concat([X.drop(X.columns[cols_to_encode], axis=1), encoded_df], axis=1) # 转为numpy数组(若后续需要数组格式) X_processed = X_processed.values print(X_processed)
关键修改点
- 改用
DataFrame处理特征,替代直接取values,更便于列类型调整与数据操作; - 将待编码列强制转为
str类型,彻底解决混合类型问题; - 直接对多列编码,删除多余的
reshape操作; - 用
pd.concat合并数据,避免索引混乱; - 添加
handle_unknown='ignore'参数,提升代码对未知类别的鲁棒性。
内容的提问来源于stack exchange,提问作者v4ts
相关产品推荐
相关产品推荐

