python - 与 pandas 系列切片的混淆

标签 python pandas slice

我有一个 pandas DataFrame,其中一列是出租车行驶的行程距离。我在用着 此列上的 value_counts() 以便查看最常见的行程距离。

b = df['trip_distance'].value_counts()

对象 b 是 pandas Series 对象。为了完整起见,本系列的前 5 行是

1.00     21815
0.90     18915
0.80     18449
1.10     18263
1.20     17823

这意味着最常见的行程距离为 1,出现了 21815 次,其余相同。

但是,如果我输入 b[0:4] 而不是打印该系列的前 4 个元素,它会找到与 0 行程距离相对应的元素,并开始打印所有行程距离,直到达到行程距离 4。当然,如果行程距离 4 在行程距离 0 之前,则返回一个空 Series。

尽管如此,当我在自定义系列上尝试时

a = pd.Series([3, 1, 2, 3, 4, 4, 5]).value_counts()

打印a给出

 4    2
 3    2
 5    1
 2    1
 1    1

当我尝试对这个系列进行切片时,即当我输入 a[0, 3] 时,我得到了预期的结果

4    2
3    2
5    1

有谁知道为什么会这样吗? 我知道这可以使用 iloc/loc 来完成,我只是好奇为什么切片在一个列表中有效,但在另一个列表中无效。

提前致谢。

最佳答案

在对 Series 中的值(或数据帧中的行)进行索引时,我始终建议您使用 .loc.iloc 索引访问器。本质上,通过使用这些访问器,您明确告诉 pandas loc:“此切片将基于索引的顺序”或 iloc:“此切片将基于关于值的顺序”。当您不使用 loc/iloc (例如您的情况)并且有数字索引时,棘手的部分就会出现。当您不使用其中任何一个时,pandas 会尝试推断您是指索引顺序还是值的顺序。本质上,如果您使用一系列数字进行切片,pandas 会假设您正在尝试使用值的位置 - 忽略索引。

import pandas as pd

data = pd.Series([5,6,7,8,9], index=range(10, 15))
print(data)

10    5
11    6
12    7
13    8
14    9
dtype: int64

使用.loc从索引中获取与切片“a”到“c”相对应的值:

# Slice based on the index values 11 to 13
data.loc[11:13]
11    6
12    7
13    8
dtype: int64

但是,如果我们想要基于其在系列中的位置的值,我们可以使用iloc。您还会注意到,iloc 生成的切片不包含最终值(例如,我们仅返回元素 1 和 2,并在下面的示例中省略 3)。而在上面使用 loc 的示例中,我们返回了索引中对应于 11、12 和 13 的元素。

data.iloc[1:3]
11    6
12    7
dtype: int64

既然已经说过了,我希望你明白为什么这意味着什么非常不清楚:

data[11:13]

我们是否要求 pandas 在索引中找到值 11 到 13 存在的位置并给我们该切片?或者我们要的是这个系列的第 12 个和第 13 个元素?在本例中,pandas 使用了后者(见下文)。但是,我鼓励您始终使用 loc.iloc 切片为 Series 或 DataFrame,以避免这种歧义。

data[11:13]
Series([], dtype: int64)

这只是为了对基于整数的索引进行切片。您的问题来自 pandas 如何实现 float 类型索引(这是真正的思维扭曲):

data.index = data.index.astype("float")
print(data)
10.0    5
11.0    6
12.0    7
13.0    8
14.0    9
dtype: int64

现在突然之间,您可以执行此操作,它会返回值,就像您使用 .loc 一样:

data[11:13]
11.0    6
12.0    7
13.0    8
dtype: int64

那么什么给出了呢?本质上,必须做出决定。需要某种类型的默认行为来切片为系列,不幸的是,它依赖于索引,这使得它在索引数据类型之间感觉不稳定。值得庆幸的是,通过使用 lociloc,您可以避免所有这些困惑。

关于python - 与 pandas 系列切片的混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64325834/

相关文章:

python - 如何在新的 virtualenv 上安装 PyQt5 并在 IDLE 上工作

python - 结合 maybe 和 seq monads : confused at the output

python - 在 pandas python 中匹配一个表并将值映射到另一个表

go - 工作超过 slice 的末尾是惯用的吗?

sql - 将行扫描成 slice

python - paho MQTT 不响应 docker 容器

python - 在 Python 3.x 下将字符串传递给 ctypes 函数

python - 将数据帧从其他数据帧中删除两列

python - pandas - 按 index.name 与数据帧相交

python - 切片操作是否总是分配一个新对象?