我正在对pandas数据帧进行切片,并且与numpy和普通的python切片相比,我似乎正在使用.loc
获得意外的切片。请参见下面的示例。
>>> import pandas as pd
>>> a = pd.DataFrame([[0,1,2],[3,4,5],[4,5,6],[9,10,11],[34,2,1]])
>>> a
0 1 2
0 0 1 2
1 3 4 5
2 4 5 6
3 9 10 11
4 34 2 1
>>> a.loc[1:3, :]
0 1 2
1 3 4 5
2 4 5 6
3 9 10 11
>>> a.values[1:3, :]
array([[3, 4, 5],
[4, 5, 6]])
有趣的是,这仅发生在.loc
上,而不发生在.iloc
上。
>>> a.iloc[1:3, :]
0 1 2
1 3 4 5
2 4 5 6
因此,.loc
似乎包含终止索引,而numpy和.iloc
则没有。
通过评论,看来这不是一个错误,我们得到了很好的警告。但是为什么会这样呢?
答案 0 :(得分:6)
记住.loc
是基于主要标签的索引。使用non-RangeIndex时,包含stop端点的决定变得更加明显:
df = pd.DataFrame([1,2,3,4], index=list('achz'))
# 0
#a 1
#c 2
#h 3
#z 4
如果我想选择'a'
和'h'
(包括两端)之间的所有行,我只会知道'a'
和'h'
。为了与其他python切片保持一致,您还需要知道'h'
之后是哪个索引,在本例中为'z'
,但可能是任何索引。
答案 1 :(得分:3)
除docs中的点外,使用pandas
的{{1}}切片索引还基于不基于单元格索引。实际上,它是基于基于值的索引(在熊猫文档中,它称为“基于标签”,但对于数字数据,我更喜欢术语“基于值”),而对于.loc
,它是传统的numpy样式单元格索引。
此外,基于值的索引包含右值,而单元格索引则不包含右值。只需尝试以下操作:
.iloc
为您的问题提供明确的答案,为什么它是正确的:
至少在我看来,使用值/标签作为索引时,包括最后一个索引是很直观的。据我所知,这是关于已实现功能的工作方式的设计决定。