使用Pandas .iloc仍报Index out of bounds error问题求助
嘿,这个问题我之前处理欺诈检测数据集时也碰到过,咱们来理清楚问题出在哪:
核心原因:iloc和loc的本质区别搞混了
你用dataset[dataset.Class == 1].index拿到的是数据集的标签索引(也就是每一行的"名字",可能是原始行号,也可能是经过操作后保留的非连续值),但iloc是按整数位置(从0开始的连续下标,比如第1行是0,第2行是1,以此类推)来取值的,这俩完全不是一回事!
举个直观的例子:假设你的数据集原本有100行,后来你删除了第50行,这时候数据集的标签索引会变成[0,1,...,49,51,...,99],但整数位置还是0到98。如果你拿到的欺诈样本索引里有51(标签索引),用iloc[51]找的是第52个位置的行,而你的数据集现在只有99行,自然就会报"out-of-bounds"了。
另外还有一种可能:你在提取fraud_indices之后,不小心修改了原dataset(比如删了行、重置了索引但没更新),导致原来的标签索引现在已经不存在于数据集里了。
快速解决办法
给你几个靠谱的解决方案,按推荐程度排序:
最直接:用
loc代替ilocloc就是专门按标签索引取值的,完美匹配你拿到的fraud_indices:fraud_samples = dataset.loc[fraud_indices, :]一步到位直接提取子集
其实没必要先拿索引再取子集,直接一行代码就能得到你要的欺诈样本子集:fraud_samples = dataset[dataset.Class == 1].copy()加
copy()是为了避免后续修改子集时影响原数据集(Pandas默认是视图引用)。如果一定要用iloc:转成整数位置
先把标签索引转换成对应的整数位置,再用iloc:# 获取标签索引对应的整数位置 fraud_positions = dataset.index.get_indexer(fraud_indices) # 过滤掉可能的无效位置(比如数据集被修改后不存在的索引) valid_positions = fraud_positions[fraud_positions != -1] fraud_samples = dataset.iloc[valid_positions, :]
总结
这个问题本质就是对Pandas的两种索引方式理解不到位——记住:iloc认"位置",loc认"标签",下次再取子集时先想清楚自己手里的是哪种索引就行啦!
内容的提问来源于stack exchange,提问作者Vin

