You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OneHotEncoder处理测试数据时触发isnan TypeError问题排查

问题描述

计算线性回归与树模型特征重要性时,在测试数据的OneHotEncoder处理阶段触发如下错误:

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

数据集存在空值,核心疑惑:

  • 训练集包含同样空值却未报错
  • 空值是否不被OneHotEncoder支持
  • 如何解决该问题
相关代码
# 读取训练数据集
df_train = pd.read_excel('/content/feature importance training profiles.xlsx')
# train_shuffled = df_train.sample(frac=1)

# 划分训练集特征与标签
x_df_train = df_train[['Name', 'middleName', 'lastnName', 'Certification', 'Location', 'College', 'Degree', 'Jobs', 'Company', 'Date', 'LocationJob']]
y_df_train = df_train['Label']

# 训练集特征独热编码
skencoder = OneHotEncoder(handle_unknown='ignore')
sk_data_train = skencoder.fit_transform(x_df_train[['Name', 'middleName', 'lastnName', 'Certification', 'Location', 'College', 'Degree', 'Jobs', 'Company', 'Date', 'LocationJob']])

# 读取测试数据集
df_test = pd.read_excel('/content/feature importance testing profiles.xlsx')
# test_shuffled = df_test.sample(frac=1)

# 划分测试集特征与标签
x_df_test = df_test[['Name', 'middleName', 'lastnName', 'Certification', 'Location', 'College', 'Degree', 'Jobs', 'Company', 'Date', 'LocationJob']]
y_df_test = df_test['Label']

# 测试集特征独热编码(触发错误)
sk_data_test = skencoder.transform(x_df_test[['Name', 'middleName', 'lastnName', 'Certification', 'Location', 'College', 'Degree', 'Jobs', 'Company', 'Date', 'LocationJob']])

X, y = make_classification(
    n_samples=63,
    n_features=11,
    n_informative=11,
    n_redundant=0,
    n_repeated=0,
    n_classes=2,
    random_state=0,
    shuffle=True,
)
# X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=42)

feature_names = [f"feature {i}" for i in range(X.shape[1])]
forest = RandomForestClassifier(random_state=0)
forest.fit(sk_data_train, y_df_train)

importance = forest.feature_importances_
print(importance)

std = np.std([tree.feature_importances_ for tree in forest.estimators_], axis=0)
forest_importances = pd.Series(importance, index=feature_names)

fig, ax = plt.subplots()
forest_importances.plot.bar(yerr=std, ax=ax)
ax.set_title("Feature importances using MDI")
ax.set_ylabel("Mean decrease in impurity")
fig.tight_layout()

y_pred = forest.predict(sk_data_test)
print("ACCURACY OF THE MODEL: ", metrics.accuracy_score(y_df_test, y_pred))
问题分析与解决方案

核心原因

  1. 空值类型不统一:训练集的空值可能是字符串类型(如空字符串""),而测试集的空值是数值型空值(np.nan/pd.NA)。OneHotEncoder可以处理字符串类别的空值,但无法兼容数值型空值——内部调用isnan函数时,无法对字符串类型执行该操作,触发类型不匹配错误。
  2. OneHotEncoder的空值支持限制:该编码器不原生支持数值型空值,仅能处理离散的类别值(包括字符串类型的空值)。

训练集未报错的原因

训练集读取时,空值可能被自动转换为字符串类型(如Excel空白单元格被读取为空字符串),OneHotEncoder将其当作普通类别完成fit操作;而测试集的空值被读取为np.nan(数值型空),transform时触发类型冲突。

解决方案

方案1:统一空值为特定类别

将训练集和测试集的所有空值替换为统一的类别(如"Missing"),确保数据类型一致:

# 处理训练集空值
x_df_train = x_df_train.fillna("Missing")
# 处理测试集空值
x_df_test = x_df_test.fillna("Missing")

方案2:强制统一特征类型

将所有特征列转换为字符串类型,避免混合类型导致的错误:

# 转换训练集特征为字符串
x_df_train = x_df_train.astype(str)
# 转换测试集特征为字符串
x_df_test = x_df_test.astype(str)
# 把转换后出现的"nan"字符串替换为统一类别
x_df_train = x_df_train.replace("nan", "Missing")
x_df_test = x_df_test.replace("nan", "Missing")

方案3:删除含空值的样本(不推荐,会丢失数据)

如果空值样本占比极低,可以直接删除:

x_df_train = x_df_train.dropna()
y_df_train = y_df_train.loc[x_df_train.index]
x_df_test = x_df_test.dropna()
y_df_test = y_df_test.loc[x_df_test.index]

内容的提问来源于stack exchange,提问作者Jesper Ezra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 22:44:54