pandas DataFrame切片重设索引后如何保留原始索引供iloc按原位置取值
问题说明
初始构造的dataset DataFrame内容如下:
import pandas as pd dataset = pd.DataFrame({'id':list('123456'), 'B':[4,5,4,5,5,4], 'C':[7,8,9,4,2,3]}) print(dataset)
id B C 0 1 4 7 1 2 5 8 2 3 4 9 3 4 5 4 4 5 5 2 5 6 4 3
执行iloc[2:5]切片后得到子集:
dataset = dataset.iloc[2:5] print(dataset)
id B C 2 3 4 9 3 4 5 4 4 5 5 2
将id列设为新索引后:
dataset.set_index("id", inplace=True) print(dataset)
B C id 3 4 9 4 5 4 5 5 2
当前遇到的问题:希望执行dataset.iloc[3]时返回当前数据集的第一行(对应原始全量数据中位置为3的行),但实际触发out of bound越界错误,只有dataset.iloc[0]能返回第一行,需要找到保留原始位置索引的实现方法。
解答
首先明确核心规则:pandas中iloc的取值逻辑是固定的,永远基于当前DataFrame的行顺序从0开始计数位置,和数据集之前的索引、切片历史没有任何关联。你切片后的数据集只剩3行,iloc合法的入参只能是0、1、2,传入3必然触发越界,不存在直接修改iloc逻辑让它识别原始位置的方法,强行魔改只会引发后续数据处理的逻辑混乱。
可以根据你的实际需求选以下两种实现方案:
- 方案1:将原始位置存储为普通列,按需筛选
切片后、设置id为新索引前,先把原始整数索引存为单独列,后续按列值筛选即可:
执行后得到的dataset = dataset.iloc[2:5] # 保存原始位置到普通列 dataset['original_loc'] = dataset.index dataset.set_index("id", inplace=True) # 取原始位置为3的行 target_row = dataset[dataset['original_loc'] == 3]target_row就是你需要的当前数据集第一行。 - 方案2:设置多层索引,用
loc按原始位置取值
如果希望索引用法更简洁,可以把原始整数位置和id共同设为多层索引,用loc(按索引值匹配,而非当前位置)直接取值:
该写法和你预期的dataset = dataset.iloc[2:5] # 构建多层索引:第一层是原始位置,第二层是id dataset = dataset.set_index([dataset.index, "id"]) # 直接按原始位置3取对应行 target_row = dataset.loc[3]iloc[3]使用体验一致,不会触发越界问题。
内容的提问来源于stack exchange,提问作者Paul Jiang
相关产品推荐
相关产品推荐

