K-means聚类预测报错:传入列数与数据列数不匹配求助
问题分析与解决方案
核心错误原因
报错ValueError: 23 columns passed, passed data had 9 columns的直接原因:
- 创建
new_data时,指定的列名是经过one-hot编码后的filtered_df.columns(共23列),但传入的原始数据只有9个特征值,列数完全不匹配。 - 经过
pd.get_dummies处理后,filtered_df的列数已从原始9列扩展为23列(每个分类特征被拆分为多个二进制列),但新数据仍用原始9个值,自然对应不上。
代码中的其他问题
- 重复训练KMeans:连续两次调用
kmeans.fit(filtered_df),属于冗余操作,一次即可。 - LabelEncoder滥用:用同一个
encoder实例对所有分类特征编码,会导致编码规则混乱(不同特征的相同标签会被编出不同值),应为每个分类特征单独创建编码器,或直接用独热编码更适配聚类场景。 - 预处理冗余:先对分类特征做LabelEncoder,又立刻用
pd.get_dummies做独热编码,两步重复(直接对原始字符串分类特征做独热编码更高效)。 - Scaler重复拟合:两次对
Age at ablation列做scaler.fit_transform,第二次拟合会覆盖第一次的均值和方差,导致后续新数据缩放规则错误。
修正后的完整代码
import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.cluster import KMeans # 读取数据 file_path = r'\\uh01502854.bmwgroup.net\home$\Q554217\BSM.xlsx' df = pd.read_excel(file_path) # 筛选所需列 filtered_df = df[["Age at ablation", "Sex", "diabetes", "CVA/TIA", "MI", "CCF", "HTN", "anti arrhythmic", "rate control"]] # 处理数值列缺失值(用均值填充,可根据实际调整) filtered_df["Age at ablation"] = pd.to_numeric(filtered_df["Age at ablation"], errors='coerce') filtered_df["Age at ablation"] = filtered_df["Age at ablation"].fillna(filtered_df["Age at ablation"].mean()) # 处理分类列缺失值(替换为统一标识,可根据实际调整) categorical_cols = ["Sex", "diabetes", "CVA/TIA", "MI", "CCF", "HTN", "anti arrhythmic", "rate control"] filtered_df[categorical_cols] = filtered_df[categorical_cols].fillna("Unknown").astype(str) # 标准化数值列 scaler = StandardScaler() numerical_col = ["Age at ablation"] filtered_df[numerical_col] = scaler.fit_transform(filtered_df[numerical_col]) # 独热编码分类列 processed_df = pd.get_dummies(filtered_df, columns=categorical_cols) # 训练KMeans模型 kmeans = KMeans(n_clusters=2, random_state=0) kmeans.fit(processed_df) # 处理新数据 # 1. 创建与原始筛选数据结构一致的新数据 new_data_raw = pd.DataFrame( [[70, 'Male', 'No', 'No', 'No', 'No', 'Yes', 'No', 'Yes']], columns=["Age at ablation", "Sex", "diabetes", "CVA/TIA", "MI", "CCF", "HTN", "anti arrhythmic", "rate control"] ) # 2. 按训练流程标准化数值列 new_data_raw[numerical_col] = scaler.transform(new_data_raw[numerical_col]) # 3. 独热编码并对齐列(保证和训练数据列数、顺序完全一致) new_data_processed = pd.get_dummies(new_data_raw, columns=categorical_cols) # 补全训练数据有但新数据缺失的列 missing_cols = set(processed_df.columns) - set(new_data_processed.columns) for col in missing_cols: new_data_processed[col] = 0 # 按训练数据的列排序 new_data_processed = new_data_processed[processed_df.columns] # 预测并输出结果 predictions = kmeans.predict(new_data_processed) print(predictions)
关键修正点说明
- 新数据处理逻辑:先创建与原始筛选数据结构一致的
new_data_raw,再严格遵循训练时的预处理流程转换,最后对齐列数和顺序。 - 预处理规则统一:训练数据与新数据使用完全相同的标准化、编码规则,避免因规则不一致导致的预测错误。
- 移除冗余操作:删除重复的模型训练、重复的特征编码步骤,精简代码逻辑。
- 缺失值处理:新增缺失值处理逻辑(实际项目中需根据数据特性调整填充策略)。
内容的提问来源于stack exchange,提问作者Jaaz Douglas
相关产品推荐
相关产品推荐

