如何修复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'
问题根源
- 索引语法混淆:若
feat是Pandas DataFrame,numpy风格的[:, mask]切片不兼容,需用.iloc[:, mask];若转为numpy数组,则直接用[:, mask],但数组无.loc属性。 - 数据类型不匹配:
label是Python列表,不能用布尔索引,需转为numpy数组。 - Matlab函数调用错误:直接调用
fitcknn、predict是Matlab函数,需通过eng.fitcknn、eng.predict调用,且需将numpy数组转为matlab兼容类型。 - 语法错误: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
相关产品推荐
相关产品推荐

