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

K折交叉验证代码报错:'(slice(None, None, None), 0)'无效键及iloc问题

K折交叉验证索引错误的解决方案

看起来你在实现K折交叉验证时踩了一个很常见的坑——混淆了pandas DataFrame和numpy数组的索引逻辑,我来帮你理清楚问题并修正代码。

错误原因分析

你遇到的两个错误本质上是同一个问题:

  • 当你用np.array_split(data, k)处理pandas DataFrame时,返回的是一个包含k个DataFrame的列表,而不是numpy数组。所以你用folds[i][:, 0]这种numpy式的索引会报错,因为DataFrame不支持这种索引语法。
  • 之后尝试folds.iloc[i]又报错,是因为folds是Python列表,而iloc是pandas DataFrame独有的方法,列表根本没有这个属性。

下面给你两种可行的修正方案,你可以根据自己的习惯选择:


方案一:纯Pandas/DataFrame操作(推荐,保持数据结构清晰)

这种方法保留DataFrame的结构,更适合后续的数据分析和预处理:

import pandas as pd
import numpy as np

data = pd.read_csv('Data_assignment1.csv')
k = 10

# 正确打乱DataFrame:用sample方法,避免破坏数据结构
data_shuffled = data.sample(frac=1, random_state=42).reset_index(drop=True)
# 分割成k个DataFrame组成的列表
folds = np.array_split(data_shuffled, k)

for i in range(k):
    # 取出第i折作为验证集,用iloc获取列(或直接用列名更直观)
    cv_df = folds[i]
    x_cv = cv_df.iloc[:, 0].values  # .values转成numpy数组(如果模型需要)
    y_cv = cv_df.iloc[:, 1].values
    
    # 合并剩余的k-1折作为训练集
    train_dfs = folds[:i] + folds[i+1:]
    train_df = pd.concat(train_dfs, axis=0)
    x_train = train_df.iloc[:, 0].values
    y_train = train_df.iloc[:, 1].values
    
    # 这里插入你的模型训练、验证逻辑
    print(f"第{i+1}折:训练样本数{len(train_df)},验证样本数{len(cv_df)}")

关键点说明:

  • 用data.sample(frac=1)打乱数据比直接np.random.shuffle(data.values)更安全,能保留DataFrame的列名和索引结构。
  • 取验证集时,先从列表中取出对应的DataFrame,再用iloc[:, 0]获取第一列(如果知道列名,比如cv_df['feature_col']会更易读)。
  • 合并训练集时,用列表切片获取除第i折外的所有DataFrame,再用pd.concat合并成一个大的DataFrame。

方案二:转成Numpy数组操作(适合习惯numpy的场景)

如果你更习惯用numpy数组处理数据,可以先把DataFrame转成numpy数组再操作:

import pandas as pd
import numpy as np

data = pd.read_csv('Data_assignment1.csv')
k = 10

# 把DataFrame转成numpy数组
data_np = data.values
# 打乱数组
np.random.shuffle(data_np)
# 分割成k个numpy数组组成的列表
folds = np.array_split(data_np, k)

for i in range(k):
    # 直接用numpy索引获取验证集
    x_cv = folds[i][:, 0]
    y_cv = folds[i][:, 1]
    
    # 合并剩余折作为训练集
    train_folds = np.delete(folds, i, 0)
    train_np = np.row_stack(train_folds)
    x_train = train_np[:, 0]
    y_train = train_np[:, 1]
    
    # 插入模型训练逻辑
    print(f"第{i+1}折:训练样本数{len(train_np)},验证样本数{len(folds[i])}")

关键点说明:

  • 先通过data.values把DataFrame转成numpy数组,这样np.array_split返回的就是numpy数组的列表,就能用[:, 0]这种熟悉的索引方式了。
  • 这种方法省去了DataFrame的操作,适合不需要保留列信息的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 21:02:55