我有一个名为“impression_data”的Pandas数据框,其中包含一个名为“site.id”的列,如下所示:
>>> impression_data['site.id']
0 62
1 189
2 191
3 62
...
此列中的每个项目都具有数据类型numpy.int64,如下所示:
>>> for i in impression_data['site.id']:
print type(i)
<type 'numpy.int64'>
<type 'numpy.int64'>
<type 'numpy.int64'>
...
正如预期的那样,只要我测试整数,成员资格测试就能很好地运行:
>>> 62 in impression_data['site.id']
True
但这是意想不到的结果:我的印象是np.int64
列不应包含任何小数值。显然我错了。这是怎么回事?
>>> 62.5 in impression_data['site.id']
True
编辑1: 列中的所有值都应该是构造的整数。为了完整起见,我还执行了以下转换操作并且没有遇到任何错误:
impression_data['site.id'] = impression_data['site.id'].astype('int')
根据@ BremBam在评论中的建议,我试过
impression_data['site.id'].map(type).unique()
产生
[<type 'numpy.int64'>]
我正在使用的最小示例和真实数据文件就在这里 https://dl.dropboxusercontent.com/u/28347262/SE%20Pandas%20Int64%20Membership%20Testing/cm_impression.csv
在这里
答案 0 :(得分:1)
这是a bug in pandas。在包含测试完成之前,该值将转换为索引的类型,因此62.5
将转换为62
。 (请注意,系列的in
会检查该值是否在索引中,而不是值。)
我相信你可以通过62.5 in impression_data.values
获得你想要的东西。
答案 1 :(得分:0)
首先,系列中的成员资格测试是索引,而不是值:
>>> s = pd.Series([10,20,30])
>>> s
0 10
1 20
2 30
dtype: int64
>>> 0 in s
True
>>> 10 in s
False
但你是对的:
>>> 1.5 in s
True
经过一些工作,这似乎是因为__contains__
中的Int64HashTable
:
cdef class Int64HashTable: #(HashTable):
[...]
def __contains__(self, object key):
cdef khiter_t k
k = kh_get_int64(self.table, key)
return k != self.table.n_buckets
key
以浮动形式出现,但我们有
inline khint_t kh_get_int64(kh_int64_t*, int64_t)
因此我认为在进行比较之前它会被强制转换为整数。