
本文详解如何从 pandas dataframe 中正确提取特征(x)和标签(y),避免因错误切片导致的维度错误(如“too many indices for array”),并确保 x_train 为 (100, 2)、y_train 为 (100, 1) 的合规形状,同时支持后续可视化与建模。
在机器学习数据预处理中,将原始表格数据正确拆分为特征矩阵 X_train 和标签向量 y_train 是关键一步。你当前的代码存在两个核心问题:
- 索引逻辑错误:data[0, [0,2]] 仅取第 0 行的第 0 和第 2 列,返回的是 shape 为 (2,) 的一维数组,而非全部 100 行;
- 维度不匹配:y_train 被错误赋值为与 X_train 相同的二维切片,导致后续布尔索引 y_train == 0 作用于二维数组时,无法直接用于索引二维 X_train(报错 “too many indices for array”)。
✅ 正确做法是使用 NumPy 切片语法,按行(所有行)和列(指定列范围)进行二维索引:
# 正确加载并分离数据(保持 NumPy 数组格式)
df = pd.read_excel('A3data.xlsx')
data = df[['Exam1', 'Exam2', 'Admission Decision']].to_numpy() # shape: (100, 3)
# 提取前两列作为特征 X_train → shape (100, 2)
X_train = data[:, :2] # 或 data[:, [0, 1]]
# 提取第三列(标签)并保持二维结构 → shape (100, 1)
y_train = data[:, 2:3] # 关键:用切片 2:3 而非索引 [2],保留第二维⚠️ 注意:data[:, 2] 返回 shape (100,) 的一维数组,而 data[:, 2:3] 返回 (100, 1) —— 后者才能与 X_train 兼容进行布尔索引。
完成上述操作后,可视化即可正常运行:
# 安全的布尔索引(y_train 是 (100, 1),y_train == 0 生成 (100, 1) 布尔数组)
x_class0 = X_train[y_train.ravel() == 0] # 推荐:ravel() 转为 1D 布尔索引更直观
x_class1 = X_train[y_train.ravel() == 1]
# 绘图
plt.scatter(x_class0[:, 0], x_class0[:, 1], color='blue', label='Not Admitted')
plt.scatter(x_class1[:, 0], x_class1[:, 1], color='red', label='Admitted')
plt.xlabel('Exam 1 Score')
plt.ylabel('Exam 2 Score')
plt.legend()
plt.show()? 进阶建议:
- 若需保留列名语义与类型安全,推荐全程使用 Pandas(无需转 NumPy):
X_train = df[['Exam1', 'Exam2']] # DataFrame, shape (100, 2) y_train = df['Admission Decision'] # Series, shape (100,)
此时 X_train[y_train == 0] 可直接工作(Pandas 自动对齐索引)。
- 实际项目中,请务必在分离 X/y 之前执行 train_test_split,防止数据泄露。
总结:牢记 NumPy 切片中 : 表示“全部”,start:end 保持维度,避免用单索引破坏结构——这是规避维度错误最简单也最根本的原则。










