我可以尝试解释一下这种行为。在 Pandas 中,您可以通过position 或label 进行选择,重要的是要记住每一行/列将始终有一个position“名称”和一个label 名称。在列的情况下,这种区别通常很容易看出,因为我们通常给列提供字符串名称。当您明确使用 .iloc 与 .loc 切片时,差异也很明显。最后s[X]是indexing,其中s[X:Y]是slicing,两个动作的行为是不同的。
例子:
df = pd.DataFrame({'a':[1,2,3], 'b': [3,3,4]})
df.iloc[:,0]
df.loc[:,'a']
两者都会返回
0 1
1 2
2 3
Name: a, dtype: int64
现在,在您的情况下发生的情况是,您在声明 s.index = [11,12,13,14] 时覆盖了索引名称。您可以通过在此更改之前和之后检查索引来看到这一点。之前,如果您运行s.index,您会看到它是RangeIndex(start=0, stop=4, step=1)。更改索引后,变为Int64Index([11, 12, 13, 14], dtype='int64')。
为什么这很重要?因为虽然你覆盖了索引的labels,但是它们每一个的位置还是和以前一样。所以,当你打电话时
s[0:2]
您正在切片按位置(文档中的this section 解释说它等同于.iloc。但是,当您运行时
s[0]
Pandas 认为您想通过 label 进行选择,因此它开始寻找不再存在的 label 0,因为您覆盖了它。在选择数据框列的上下文中考虑方括号选择:你会说df["column"](所以你要求label 的列),所以在系列的上下文中也是如此。
总之,系列索引会发生以下情况:
- 如果您使用字符串索引标签,并按
string 进行索引,Pandas 将查找字符串标签。
- 如果您使用字符串索引标签,并按
integer 进行索引,Pandas 将退回到按位置索引(这就是您在评论中的示例有效的原因)。
- 如果您使用整数索引标签,并按
integer 进行索引,Pandas 将始终尝试按“标签”进行索引(这就是为什么第一种情况不起作用,因为您已经覆盖了label 0)。
这里有两篇文章解释了这种奇怪的行为:
Indexing Best Practices in Pandas.series
Retrieving values in a Series by label or position