如何使用整数索引读取DataFrame行?range生成索引传入iloc报错如何解决
报错原因
- 根本原因是混淆了Pandas的位置索引和标签索引两套体系:
iloc[]、iat[]是位置索引,入参为代表行/列顺序的整数,和DataFrame的索引取值无关;loc[]、at[]是标签索引,入参为DataFrame实际设置的行/列索引值,和行/列的顺序无关。- 第一种写法中
iterrows()返回的index是行标签,和at[]的索引规则匹配,只要标签存在就可以正常赋值。第二种写法中range()生成的index是行的位置序号,如果你修改过DataFrame的索引(比如删除行、设置自定义索引、切片得到子DataFrame),行标签和位置序号就不再一致,用位置序号作为标签传入at[]时找不到对应行,底层索引器处理异常就会抛出该报错。
- 补充说明:你打印的index类型相同、初始值都是0不代表可以通用,只有当你的DataFrame是默认的0起始连续整数索引时,标签和位置序号才会完全对等,只要索引发生过变更就会出现不匹配的问题。
解决方案
方案1:保持按位置遍历的逻辑,替换索引器
把按标签索引的at[]替换为按位置索引的iat[]即可,列需要先转换为位置序号:
for index in range(len(dataFrameCopy) - 2): # 获取目标列的位置序号 col_idx = dataFrameCopy.columns.get_loc('bullish_swing') dataFrameCopy.iat[index, col_idx] = classify_bullish_swing( dataFrameCopy.iloc[index,:], dataFrameCopy.iloc[index + 1,:], dataFrameCopy.iloc[index + 2,:] )
方案2:按标签匹配,和第一种写法逻辑对齐
提前获取行标签列表,用位置序号取对应标签再传入at[]:
row_labels = dataFrameCopy.index.tolist() for pos in range(len(row_labels) - 2): current_label = row_labels[pos] dataFrameCopy.at[current_label, 'bullish_swing'] = classify_bullish_swing( dataFrameCopy.iloc[pos,:], dataFrameCopy.iloc[pos + 1,:], dataFrameCopy.iloc[pos + 2,:] )
方案3:更高效的向量化实现(推荐)
避免循环遍历,用Pandas的滑动窗口rolling实现3行批量处理,性能远高于逐行循环:
def wrap_classify(window): return classify_bullish_swing(window.iloc[0], window.iloc[1], window.iloc[2]) # 滑动窗口处理后前移2位,和对应行匹配 dataFrameCopy['bullish_swing'] = dataFrameCopy.rolling(3).apply(wrap_classify).shift(-2)
内容的提问来源于stack exchange,提问作者HelloWorld
相关产品推荐
相关产品推荐

