熊猫' isin
方法似乎有一个dtype依赖(使用Python 3.5和pandas 0.19.2)。我偶然在一个相关的topic偶然发现了这个问题,我们无法解释isin的非工作行为。这是一个例子:
df = pd.DataFrame([[1.2, 0.3, 1.5, 1.4, 1.7, 4.2]])
print(df)
0 1 2 3 4 5
0 1.2 0.3 1.5 1.4 1.7 4.2
print(df.dtypes)
0 float64
1 float64
2 float64
3 float64
4 float64
5 float64
dtype: object
# everything works as expected until here
print(df.isin([1.2, 1.4]))
0 1 2 3 4 5
0 True False False True False False
但是,当dtype转换为float32
时,isin开始失败:
df = df.apply(lambda x: x.astype("float32"))
print(df.dtypes)
0 float32
1 float32
2 float32
3 float32
4 float32
5 float32
dtype: object
print(df.isin([1.2, 1.4]))
0 1 2 3 4 5
0 False False False False False False
这是SO上类似的post。
我理解浮点并发症。但是,从用户的角度来看,谁希望将isin
用作col1 == 1 | col1 == 3 | col1 == 5
的便捷函数(简单地编写col1.isin([1, 3, 5])
),当dtypes不同并且没有给出警告时,它可能会导致无法识别的错误关于dtype偏差。
与isin
相比,df.eq
会返回不同的结果:
print(df.isin([1.2]))
0 1 2 3 4 5
0 False False False False False False
print(df.eq(1.2))
0 1 2 3 4 5
0 True False False False False False
这绝对是一种不受欢迎的行为。正如JohnE指出的那样,df.eq
似乎使用了np.isclose,而df.isin
却没有。
答案 0 :(得分:1)
也许这会让它更清晰:
>>> '%20.18f' % df[0].astype(np.float64)
'1.199999999999999956'
>>> '%20.18f' % df[0].astype(np.float32)
'1.200000047683715820'
一般来说,你不希望看到18个小数位,所以大熊猫会对要显示多少小数做出合理的选择 - 但差异仍然存在,尽管是不可见的。因此,您需要确保将float64与float64和float32与float32进行比较。这就是我们为自己选择的浮点生活......
或者,如果您一次比较一个值,则可以使用np.isclose
(在import numpy as np
之后)来确定大致相等:
>>> np.isclose( df.astype(np.float64), 1.2 )
array([[ True, False, False, False, False, False]], dtype=bool)
>>> np.isclose( df.astype(np.float32), 1.2 )
array([[ True, False, False, False, False, False]], dtype=bool)
(你不需要astype()
,当然,这只是为了证明你对float32和float64都能得到相同的答案。)
我不知道是否有办法让isin
以类似的方式工作,所以你可能需要做类似的事情:
>>> np.isclose( df, 1.2 ) | np.isclose( df, 1.4 )
array([[ True, False, False, True, False, False]], dtype=bool)
答案 1 :(得分:0)
#try this:
import numpy as np
df = df.apply(lambda x: x.astype(np.float32))
test=[1.2,1.4]
test=test.apply(lambda x: x.astype(np.float32))
df.isin(test)