提问人:cs95 提问时间:6/7/2019 最后编辑:cs95 更新时间:6/7/2019 访问量:4202
dtype 比较: == 和 isin 对 “object” 产生不同的结果
dtype comparison: == and isin produce different results for "object"
问:
最小示例:
df = pd.DataFrame({'x': ['a', 'b', 'c'], 'y': [1, 2, 3], 'z': ['d', 'e', 'f']})
df
x y z
0 a 1 d
1 b 2 e
2 c 3 f
df.dtypes
x object
y int64
z object
dtype: object
这个想法是过滤掉类型的列。我知道这可以通过 来完成,这个问题背后的动机是检查我将要向您展示的内容背后的奇怪行为。object
select_dtypes
==
(因此,)用于比较特定类型。.eq
df.dtypes == object
x True
y False
z True
dtype: bool
但是,不会:isin
df.dtypes.isin([object])
df.dtypes.isin(['object'])
x False
y False
z False
dtype: bool
OTOH,创建一个对象并传递它。np.dtype
df.dtypes.isin([np.dtype('O')])
x True
y False
z True
dtype: bool
np.isin
在这里有效,所以没有理由让它表现得有任何不同。
np.isin(df.dtypes, object)
array([ True, False, True])
np.isin(df.dtypes, 'object')
array([ True, False, True])
isin
仅在检查对象类型时似乎会引起麻烦。 给出预期的结果。df.dtypes.isin(['int'])
顺便说一句,我在 0.24 上运行这些测试。
pd.__version__
'0.24.2'
这是一个错误,还是预期的行为?
答:
7赞
root
6/7/2019
#1
在这种情况下,这归结为依赖哈希表,而在 0.20.3 中,这可能会沿着不同的代码路径使用,并根据您的 python/numpy 版本使用。pandas.Series.isin
np.in1d
请注意,和的哈希值不同,这解释了当前失败的原因:np.dtype('O')
object
In [2]: hash(np.dtype('O'))
Out[2]: 7065344498483383396
In [3]: hash(object)
Out[3]: 108607961
看起来正在对对象进行直接的相等性比较,并且与 / 的相等性内置于独立于哈希的定义中。np.in1d
object
'object'
np.dtype('O')
它还说明了 pandas 的一个更大问题:对于较小的输入情况,比较相同但具有不同哈希值的对象将失败。请考虑以下类:isin
isin
class Foo(object):
def __init__(self, hash_val):
self.hash_val = hash_val
def __hash__(self):
return self.hash_val
def __eq__(self, other):
return isinstance(other, Foo)
然后我们得到:
In [5]: s = pd.Series([Foo(0), Foo(1), Foo(2)])
In [6]: s == Foo(3)
Out[6]:
0 True
1 True
2 True
dtype: bool
In [7]: s.isin([Foo(3)])
Out[7]:
0 False
1 False
2 False
dtype: bool
In [8]: np.in1d(s.values, [Foo(3)])
Out[8]: array([ True, True, True])
这是一个错误吗?可能,但我猜这将是一个低优先级的项目,因为这是一个极端情况,并且可能以高性能的方式修复(即当前实现有一个注释,表明对象 dtypes 不应该被传递给,因为它可能会引发,所以简单地委派给是行不通的)。np.in1d
np.in1d
评论
3赞
user2357112
6/7/2019
dtype
比较是完全疯狂的,不应该像它那样行事,但如果 NumPy 开发人员现在试图改变事情,太多的现有代码会中断。正如本例所示,依赖 dtypes 与不是 实例的对象的比较是一个坏主意。numpy.dtype
0赞
Bill
10/31/2023
仅供参考,2020 年提出了一个与此问题相关的问题:dataframe.dtype.isin() 中的不一致 - 我在同一代码上的不同运行不一致。
评论
df.dtypes.isin(['object'])
在 0.24.2 中产生正确的输出。'0.24.2'
isin[object]