当 Series 包含字符串时,为什么 `in` 不搜索值

Why doesn't `in` search the values when the Series contains strings

这可能是非常基本的,但为什么 in 对包含对象或字符串的 Series 不起作用?

>>> import pandas as pd

>>> s = pd.Series(['a', 'b', 'c'])
>>> 'a' in s
False
>>> 'a' in s.astype('S1')
False

Series.__contains__ 文档相当稀疏:

[In 1]: s.__contains__?
Signature: s.__contains__(key)
Docstring: True if the key is in the info axis
File:      c:\...\lib\site-packages\pandas\core\generic.py
Type:      method

我的第一个想法是 in 只检查 "index":

>>> 1 in s
True

但是:为什么它(似乎)适用于其他类型:

>>> 1.2 in pd.Series([1.3, 1.2])
True

>>> 1 in pd.Series([1.3, 1.2])  # also works for index
True

我对可行的解决方案不感兴趣。我知道我可以简单地使用 whatever in s.valuesnp.any(s.eq(whatever))。我想知道 为什么 它会这样(或者我错过了什么?)。

之所以如此,是因为 Series 更像是 OrderedDict 而不是列表。

就像1 in {0: 5, 1: 10}是True一样,1 in pd.Series([5, 10])也是,因为索引是RangeIndex(start=0, stop=2, step=1),索引元素就像键

我明白为什么

>>> 1.2 in pd.Series([1.3, 1.2])
True

可能有点令人困惑,但这只是基于您选择的数字的巧合——1.2 在与 RangeIndex 或 Int64Index 进行比较之前被强制转换为 int,所以您实际上是在问 1 in ser.index。我个人不喜欢这种行为,但这就是它正在做的。

>>> 1.9 in pd.Series([1.3, 1.2])
True
>>> 1.2 in pd.Series([1.3, 1.2], index=[10, 20])
False

为了让强制更加明显:

In [54]: np.inf in pd.Series([1.3, 1.2])
---------------------------------------------------------------------------
OverflowError                             Traceback (most recent call last)
<ipython-input-54-b069ecc5baf6> in <module>()
----> 1 np.inf in pd.Series([1.3, 1.2])

[...]
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.__contains__ (pandas/_libs/index.c:3924)()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.__contains__ (pandas/_libs/hashtable.c:13569)()

OverflowError: cannot convert float infinity to integer