当 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.values
或 np.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
这可能是非常基本的,但为什么 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.values
或 np.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