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

含缺失值的有序/无序分类与数值数据的OneHot编解码及KNN填充

处理含有序/无序分类列的DataFrame缺失值填充与编码还原

问题分析

原始代码存在以下核心问题:

  • 未区分有序分类列与无序分类列的编码逻辑:有序分类(如category_with_order的a<b<c<d层级关系)应使用序数编码,而非独热编码;仅无序分类(如category_without_order)适合独热编码
  • 直接对含缺失值的分类列做独热编码会生成异常的nan列
  • 数值列sugar、salt被存储为字符串类型,无法直接用于KNN填充计算
  • 错误拼接原数据与编码后数据,未正确构建用于填充的特征矩阵

修正后的完整代码

import pandas as pd
import numpy as np
from sklearn.preprocessing import OrdinalEncoder, OneHotEncoder
from sklearn.impute import KNNImputer

# 1. 初始化数据并预处理数值列
data = {
    'category_with_order': ['a', 'b', 'c','d',np.nan],
    'category_without_order': ['plant',np.nan,'salad','meat', 'drinks'],
    'sugar': ['1',np.nan, '2', '2',np.nan],
    'salt': ['1',np.nan, '2', '1',np.nan]
}
df = pd.DataFrame(data)

# 将字符串类型的数值列转为浮点型
df[['sugar', 'salt']] = df[['sugar', 'salt']].astype(float)

# 2. 区分有序/无序分类列进行编码
# 有序分类列编码:指定类别顺序,保留缺失值
ordinal_encoder = OrdinalEncoder(categories=[['a', 'b', 'c', 'd']], handle_unknown='use_encoded_value', unknown_value=np.nan)
encoded_ordinal = pd.DataFrame(ordinal_encoder.fit_transform(df[['category_with_order']]), columns=['category_with_order'])

# 无序分类列编码:临时填充缺失值避免生成nan列
onehot_encoder = OneHotEncoder(sparse_output=False, handle_unknown='ignore')
# 临时用占位符填充缺失值,编码后再处理
temp_onehot_input = df[['category_without_order']].fillna('temp_missing')
encoded_onehot = pd.DataFrame(onehot_encoder.fit_transform(temp_onehot_input), columns=onehot_encoder.get_feature_names_out())

# 3. 构建完整特征矩阵
feature_matrix = pd.concat([encoded_ordinal, encoded_onehot, df[['sugar', 'salt']]], axis=1)

# 4. KNN填充所有缺失值
knn_imputer = KNNImputer(n_neighbors=1)
filled_matrix = knn_imputer.fit_transform(feature_matrix)
filled_feature_df = pd.DataFrame(filled_matrix, columns=feature_matrix.columns)

# 5. 解码还原原始分类列
# 还原有序分类列
filled_feature_df['category_with_order'] = ordinal_encoder.inverse_transform(filled_feature_df[['category_with_order']])

# 还原无序分类列:将独热编码转为原始类别
onehot_cols = onehot_encoder.get_feature_names_out()
# 找到每一行概率最高的类别索引,映射回原始值
filled_onehot_indices = filled_feature_df[onehot_cols].idxmax(axis=1).str.replace('category_without_order_', '')
filled_feature_df['category_without_order'] = filled_onehot_indices.replace('temp_missing', np.nan)  # 还原临时占位符

# 6. 整理最终结果,匹配原始表头
final_df = filled_feature_df[df.columns]
print("填充后的最终DataFrame:")
print(final_df)

关键步骤说明

  • 数值列预处理:将字符串类型的sugar、salt转为浮点型,确保KNNImputer可基于数值距离计算填充值
  • 分类编码区分:
    • 有序分类列用OrdinalEncoder指定类别顺序,保留缺失值标记,保证层级关系不丢失
    • 无序分类列用OneHotEncoder时,先临时填充缺失值避免生成异常nan列,后续再还原
  • 缺失值填充:基于编码后的完整特征矩阵做KNN填充,覆盖分类、数值列的所有缺失值
  • 解码还原:通过编码器的inverse_transform方法将编码特征转回原始分类值,最终得到与原始表头一致的填充后DataFrame

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 01:40:26