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

如何修复TypeError: '(slice(None, None, None), array([...]))'无效键错误?

问题:特征选择中索引切片引发的TypeError与AttributeError解决

问题场景

在使用二进制灰狼优化算法(BGWO2)结合KNN进行特征选择时,运行代码触发TypeError,尝试用.loc修复又出现AttributeError,核心报错集中在特征矩阵的索引切片操作上。

原始代码

from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
import matlab.engine
import numpy as np  # 原代码遗漏导入

eng = matlab.engine.start_matlab()
feat = tfidfvect  # 假设tfidfvect是TfidfVectorizer输出的DataFrame或ndarray
label = []
print(label)
for i in np.arange(1,len(dataset.data)+1).reshape(-1):
    label.append(i)
print("--------")
print(label)

def jFitnessFunction(feat ,label ,X ,x_train, x_test ):
    if sum(X == 1) == 0:
        cost = inf  # 未定义inf,需用np.inf
    else:
        cost = jwrapperKNN(feat[:,X == 1],label,x_train, x_test)
    return cost

def jwrapperKNN(sFeat ,label ,x_train, x_test):
    #---// Parameter setting for k-value of KNN //
    k = 5
    xtrain = sFeat[x_train == 1,:]
    ytrain = label(x_train == 1)  # 列表不能用函数式索引,且语法错误
    xvalid = sFeat[x_test == 1,:]
    yvalid = label(x_test == 1)
    Model = fitcknn(xtrain,ytrain,'NumNeighbors',k)  # 直接调用Matlab函数错误,需通过eng
    pred = predict(Model,xvalid)
    num_valid = len(yvalid)
    correct = 0
    for i in np.arange(1,num_valid+1).reshape(-1):
        if yvalid(i)==pred(i):  # Python索引用[],不是()
            correct = correct + 1
            
    Acc = correct / num_valid
    error = 1 - Acc
    return error
    return cost  # 冗余返回

触发的错误

1. 初始TypeError

TypeError                                 Traceback (most recent call     last)
~\AppData\Local\Temp/ipykernel_17344/2041135029.py in <module>
 26 max_Iter = 100
 27 # Binary Grey Wolf Optimization
---> 28 sFeat,Sf,Nf,curve = jBGWO2(feat,label,N,max_Iter,x_train, x_test)
 29 # Plot convergence curve
 30 eng.plt.plot(np.arange(1,max_Iter+1),curve)
~\AppData\Local\Temp/ipykernel_17344/2712339248.py in jBGWO2(feat, label, N, max_Iter, x_train, x_test)
 16     fit = np.zeros((1,N))
 17     for i in range(N):
---> 18         fit[i] = fun(feat,label,X[i,:],x_train, x_test)
 19 
 20     fit.sort(reverse=true)
~\AppData\Local\Temp/ipykernel_17344/1835931109.py in jFitnessFunction(feat, label, X, x_train, x_test)
 23         cost = inf
 24     else:
---> 25         cost = jwrapperKNN(feat[:,X == 1],label,x_train, x_test)
 26     return cost
 27 
 ~\anaconda3\lib\site-packages\pandas\core\frame.py in __getitem__(self, key)
3456             if self.columns.nlevels > 1:
3457                 return self._getitem_multilevel(key)
 --> 3458             indexer = self.columns.get_loc(key)
3459             if is_integer(indexer):
3460                 indexer = [indexer]
~\anaconda3\lib\site-packages\pandas\core\indexes\base.py in get_loc(self, key, method, tolerance)
3359             casted_key = self._maybe_cast_indexer(key)
3360             try:
 --> 3361                 return self._engine.get_loc(casted_key)
3362             except KeyError as err:
3363                 raise KeyError(key) from err
 ~\anaconda3\lib\site-packages\pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc()

 ~\anaconda3\lib\site-packages\pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc()
TypeError: '(slice(None, None, None), array([False, False,  True, ...,  True,  True, False]))' is an invalid key

2. 使用.loc后的AttributeError

attributeerror: 'numpy.ndarray' object has no attribute 'loc'

问题根源

  1. 索引语法混淆:若feat是Pandas DataFrame,numpy风格的[:, mask]切片不兼容,需用.iloc[:, mask];若转为numpy数组,则直接用[:, mask],但数组无.loc属性。
  2. 数据类型不匹配:label是Python列表,不能用布尔索引,需转为numpy数组。
  3. Matlab函数调用错误:直接调用fitcknn、predict是Matlab函数,需通过eng.fitcknn、eng.predict调用,且需将numpy数组转为matlab兼容类型。
  4. 语法错误:Python索引用方括号[],而非Matlab的圆括号();inf未定义,需用np.inf。

修复后的代码

from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
import matlab.engine
import numpy as np

eng = matlab.engine.start_matlab()
# 确保feat是numpy数组,若原tfidfvect是DataFrame则用.values或.to_numpy()
feat = tfidfvect.to_numpy() if hasattr(tfidfvect, 'to_numpy') else tfidfvect
# 直接生成label为numpy数组,替代循环
label = np.arange(1, len(dataset.data)+1)
print(label)

def jFitnessFunction(feat, label, X, x_train, x_test):
    selected_idx = X == 1
    if not np.any(selected_idx):
        cost = np.inf
    else:
        cost = jwrapperKNN(feat[:, selected_idx], label, x_train, x_test)
    return cost

def jwrapperKNN(sFeat, label, x_train, x_test):
    k = 5
    # 布尔索引筛选训练/验证集,确保x_train/x_test是布尔数组
    xtrain = sFeat[x_train == 1, :]
    ytrain = label[x_train == 1]
    xvalid = sFeat[x_test == 1, :]
    yvalid = label[x_test == 1]
    
    # 将numpy数组转为matlab矩阵,适配Matlab函数
    xtrain_mat = matlab.double(xtrain.tolist())
    ytrain_mat = matlab.double(ytrain.tolist())
    xvalid_mat = matlab.double(xvalid.tolist())
    
    # 通过eng调用Matlab的fitcknn和predict
    Model = eng.fitcknn(xtrain_mat, ytrain_mat, 'NumNeighbors', k)
    pred = eng.predict(Model, xvalid_mat)
    # 将Matlab返回的预测结果转为numpy数组
    pred_np = np.array(pred).flatten()
    yvalid_np = yvalid.flatten()
    
    # 计算准确率,用numpy向量化操作替代循环
    correct = np.sum(pred_np == yvalid_np)
    Acc = correct / len(yvalid_np)
    error = 1 - Acc
    return error

关键修复点

  • 统一feat为numpy数组,避免DataFrame与数组的索引语法冲突
  • 将label转为numpy数组,支持布尔索引
  • 通过matlab.engine调用Matlab函数,并完成numpy与matlab数据类型的转换
  • 用numpy向量化操作替代循环,提升效率且避免索引语法错误
  • 正确定义np.inf替代未定义的inf

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 17:57:26