【问题标题】:Confusion with pandas Series slicing与 pandas 系列切片混淆
【发布时间】:2020-10-12 21:56:19
【问题描述】:

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

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

对象 b 是一个熊猫系列对象。为了完整起见,这个系列的前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 之前,则返回一个空系列。

不过,当我在自定义系列上尝试时

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 完成,我只是好奇为什么切片在一个列表中有效,而在另一个列表中无效。

提前致谢。

【问题讨论】:

  • 我认为不同之处在于索引的类型,尝试使用c = pd.Series([3, 1, 2, 3, 4, 4, 5]).astype(float).value_counts() 与第一个示例中的类型相同,然后c[0:3] 你会得到一个错误,因为 0 没有存在。但是如果你做a[1:3]c[1:3],你会看到区别,即使ac几乎是同一个系列
  • 我不知道是什么导致了问题,但解决方案可能是使用iloc
  • @Ben.T 是的,这是非常正确的,感谢您的指出。你对它为什么会这样表现有任何线索吗?好吧,这可能只是我猜的默认方式。
  • @ThePhoton 感谢您的建议。是的 iloc 是最好的方法,我只是偶然发现了这种特殊性,我不确定它为什么会发生。

标签: python pandas slice


【解决方案1】:

从系列(或数据帧中的行)索引值时,我始终建议您使用 .loc.iloc 索引访问器。本质上,通过使用这些访问器,您明确告诉熊猫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 分割成系列或数据帧。

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

这只是为了对基于整数的索引进行切片。您的问题来自 pandas 如何实现浮动类型索引(这是真正的绕口令):

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 来避免所有这些混淆。

【讨论】:

  • 感谢您非常详细的回答。似乎浮点数与整数索引有很大的不同。我想这只是熊猫工作的默认方式吗?但是是的 loc/iloc 是最好的切片方式。谢谢,祝你有美好的一天。
猜你喜欢
  • 1970-01-01
  • 2017-06-27
  • 1970-01-01
  • 2016-01-07
  • 2017-10-27
  • 2016-04-16
  • 1970-01-01
  • 2018-01-30
  • 2020-09-02
相关资源
最近更新 更多